home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / amiga / viewers / mpgplyr1.lha / src / video.c < prev    next >
C/C++ Source or Header  |  1992-12-08  |  91KB  |  3,350 lines

  1. /*
  2.  * Copyright (c) 1992 The Regents of the University of California.
  3.  * All rights reserved.
  4.  * 
  5.  * Permission to use, copy, modify, and distribute this software and its
  6.  * documentation for any purpose, without fee, and without written agreement is
  7.  * hereby granted, provided that the above copyright notice and the following
  8.  * two paragraphs appear in all copies of this software.
  9.  * 
  10.  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
  11.  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
  12.  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
  13.  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14.  * 
  15.  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
  16.  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  17.  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  18.  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
  19.  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  20.  */
  21. /* This file contains C code that implements
  22.  * the video decoder model.
  23.  */
  24.  
  25. #include <stdio.h>
  26. #include <assert.h>
  27.  
  28. #ifndef MIPS
  29. #include <sys/time.h>
  30. #else 
  31. #include <sys/types.h>
  32. #include <sys/systm.h>
  33. #endif
  34.  
  35. #include "decoders.h"
  36. #include "video.h"
  37. #include "util.h"
  38.  
  39. /* Declarations of functions. */
  40. static void ReconIMBlock();
  41. static void ReconPMBlock();
  42. static void ReconBMBlock();
  43. static void ReconBiMBlock();
  44. static void ReconSkippedBlock();
  45. static void DoPictureDisplay();
  46. static int ParseSeqHead();
  47. static int ParseGOP();
  48. static int ParsePicture();
  49. static int ParseSlice();
  50. static int ParseMacroBlock();
  51. static int ProcessSkippedPFrameMBlocks();
  52. static int ProcessSkippedBFrameMBlocks();
  53.  
  54. extern int ditherType;
  55.  
  56. /* Macro for returning 1 if num is positive, -1 if negative, 0 if 0. */
  57.  
  58. #define Sign(num) ((num > 0) ? 1 : ((num == 0) ? 0 : -1))
  59.  
  60. /* Declare global pointer to vid stream used for current decoding. */
  61.  
  62. VidStream *curVidStream = NULL;
  63.  
  64. /* Set up array for fast conversion from zig zag order to row/column
  65.    coordinates.
  66. */
  67.  
  68. int zigzag[64][2] = { 
  69.   0, 0, 1, 0, 0, 1, 0, 2, 1, 1, 2, 0, 3, 0, 2, 1, 1, 2, 0, 3, 0, 4, 1, 3, 
  70.   2, 2, 3, 1, 4, 0, 5, 0, 4, 1, 3, 2, 2, 3, 1, 4, 0, 5, 0, 6, 1, 5, 2, 4,
  71.   3, 3, 4, 2, 5, 1, 6, 0, 7, 0, 6, 1, 5, 2, 4, 3, 3, 4, 2, 5, 1, 6, 0, 7, 
  72.   1, 7, 2, 6, 3, 5, 4, 4, 5, 3, 6, 2, 7, 1, 7, 2, 6, 3, 5, 4, 4, 5, 3, 6,
  73.   2, 7, 3, 7, 4, 6, 5, 5, 6, 4, 7, 3, 7, 4, 6, 5, 5, 6, 4, 7, 5, 7, 6, 6,
  74.   7, 5, 7, 6, 6, 7, 7, 7 };
  75.  
  76. /* Array mapping zigzag to array pointer offset. */
  77.  
  78. int zigzag_direct[64] = {
  79.   0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12,
  80.   19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35,
  81.   42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51,
  82.   58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63};
  83.  
  84. /* Set up array for fast conversion from row/column coordinates to 
  85.    zig zag order.
  86. */
  87.  
  88. int scan[8][8] = {
  89.   { 0, 1, 5, 6, 14, 15, 27, 28},
  90.   { 2, 4, 7, 13, 16, 26, 29, 42},
  91.   { 3, 8, 12, 17, 25, 30, 41, 43},
  92.   { 9, 11, 18, 24, 31, 40, 44, 53},
  93.   { 10, 19, 23, 32, 39, 45, 52, 54},
  94.   { 20, 22, 33, 38, 46, 51, 55, 60},
  95.   { 21, 34, 37, 47, 50, 56, 59, 61},
  96.   { 35, 36, 48, 49, 57, 58, 62, 63}};
  97.  
  98. /* Initialize P and B skip flags. */
  99.  
  100. static int No_P_Flag = 0;
  101. static int No_B_Flag = 0;
  102.  
  103. /*
  104.  * We use a lookup table to make sure values stay in the 0..255 range.
  105.  * Since this is cropping (ie, x = (x < 0)?0:(x>255)?255:x; ), wee call this
  106.  * table the "crop table".
  107.  * MAX_NEG_CROP is the maximum neg/pos value we can handle.
  108.  */
  109.  
  110. #define MAX_NEG_CROP 384
  111. #define NUM_CROP_ENTRIES (256+2*MAX_NEG_CROP)
  112. #define assertCrop(x)    assert(((x) >= -MAX_NEG_CROP) && \
  113.                    ((x) <= 256+MAX_NEG_CROP))
  114. static unsigned char cropTbl[NUM_CROP_ENTRIES];
  115.  
  116. /*
  117.   The following accounts for time and size  spent in various parsing acitivites
  118.   if ANALYSIS has been defined.
  119. */
  120.  
  121. #ifdef ANALYSIS
  122.  
  123.  
  124. unsigned  int bitCount = 0;
  125.  
  126. int showmb_flag = 0;
  127. int showEachFlag = 0;
  128.  
  129. typedef struct {
  130.   int frametype;
  131.   unsigned int totsize;
  132.   unsigned int number;
  133.   unsigned int i_mbsize;
  134.   unsigned int p_mbsize;
  135.   unsigned int b_mbsize;
  136.   unsigned int bi_mbsize;
  137.   unsigned int i_mbnum;
  138.   unsigned int p_mbnum;
  139.   unsigned int b_mbnum;
  140.   unsigned int bi_mbnum;
  141.   unsigned int i_mbcbp[64];
  142.   unsigned int p_mbcbp[64];
  143.   unsigned int b_mbcbp[64];
  144.   unsigned int bi_mbcbp[64];
  145.   unsigned int i_mbcoeff[64];
  146.   unsigned int p_mbcoeff[64];
  147.   unsigned int b_mbcoeff[64];
  148.   unsigned int bi_mbcoeff[64];
  149.   double tottime;
  150. } Statval;
  151.  
  152. Statval stat_a[4];
  153. unsigned  int pictureSizeCount;
  154. unsigned  int mbSizeCount;
  155. unsigned int *mbCBPPtr, *mbCoeffPtr, *mbSizePtr;
  156. unsigned int cacheHit[8][8];
  157. unsigned int cacheMiss[8][8];
  158.  
  159. void init_stat_struct(astat) 
  160.      Statval *astat;
  161. {
  162.   int j;
  163.  
  164.   astat->frametype = 0;
  165.   astat->totsize = 0;
  166.   astat->number = 0;
  167.   astat->i_mbsize = 0;
  168.   astat->p_mbsize = 0;
  169.   astat->b_mbsize = 0;
  170.   astat->bi_mbsize = 0;
  171.   astat->i_mbnum = 0;
  172.   astat->p_mbnum = 0;
  173.   astat->b_mbnum = 0;
  174.   astat->bi_mbnum = 0;
  175.   
  176.   for (j=0; j<64; j++) {
  177.     
  178.     astat->i_mbcbp[j] = 0;
  179.     astat->p_mbcbp[j] = 0;
  180.     astat->b_mbcbp[j] = 0;
  181.     astat->bi_mbcbp[j] = 0;
  182.     astat->i_mbcoeff[j] = 0;
  183.     astat->p_mbcoeff[j] = 0;
  184.     astat->b_mbcoeff[j] = 0;
  185.     astat->bi_mbcoeff[j] = 0;
  186.   }
  187.   astat->tottime = 0.0;
  188. }
  189.  
  190. void init_stats() {
  191.   int i, j;
  192.  
  193.   for (i=0; i<4; i++) {
  194.     init_stat_struct(&(stat_a[i]));
  195.     stat_a[i].frametype = i;
  196.   }
  197.  
  198.   for (i=0; i<8; i++) {
  199.     for (j=0; j<8; j++) {
  200.       cacheHit[i][j] = 0;
  201.       cacheMiss[i][j] = 0;
  202.     }
  203.   }
  204.  
  205.   bitCount = 0;
  206. }
  207.  
  208. void PrintOneStat()
  209. {
  210.   int i;
  211.  
  212.   printf( "\n");
  213.   switch (stat_a[0].frametype) {
  214.   case I_TYPE:
  215.     printf( "I FRAME\n");
  216.     break;
  217.   case P_TYPE:
  218.     printf( "P FRAME\n");
  219.     break;
  220.   case B_TYPE:
  221.     printf( "B FRAME\n");
  222.     break;
  223.   }
  224.  
  225.   printf( "Size: %d bytes + %d bits\n", stat_a[0].totsize/8, stat_a[0].totsize%8);
  226.   if (stat_a[0].i_mbnum > 0) {
  227.     printf( "\tI Macro Block Stats:\n");
  228.     printf( "\t%d I Macroblocks\n", stat_a[0].i_mbnum);
  229.     printf( "\tAvg. Size: %d bytes + %d bits\n", 
  230.        stat_a[0].i_mbsize/(8*stat_a[0].i_mbnum), 
  231.        (stat_a[0].i_mbsize*stat_a[0].i_mbnum)%8);
  232.     printf( "\t\tCoded Block Pattern Histogram:\n");
  233.     for (i = 0; i<64; i+= 8) {
  234.       printf( "\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[0].i_mbcbp[i],
  235.          stat_a[0].i_mbcbp[i+1], stat_a[0].i_mbcbp[i+2], stat_a[0].i_mbcbp[i+3], 
  236.          stat_a[0].i_mbcbp[i+4], stat_a[0].i_mbcbp[i+5], stat_a[0].i_mbcbp[i+6], 
  237.          stat_a[0].i_mbcbp[i+7]);
  238.     }
  239.     printf( "\n\t\tNumber of Coefficients/Block Histogram:\n");
  240.     for (i = 0; i<64; i+= 8) {
  241.       printf( "\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[0].i_mbcoeff[i],
  242.          stat_a[0].i_mbcoeff[i+1], stat_a[0].i_mbcoeff[i+2], 
  243.          stat_a[0].i_mbcoeff[i+3], stat_a[0].i_mbcoeff[i+4], 
  244.          stat_a[0].i_mbcoeff[i+5], stat_a[0].i_mbcoeff[i+6], 
  245.          stat_a[0].i_mbcoeff[i+7]);
  246.     }
  247.   }
  248.  
  249.   if (stat_a[0].p_mbnum > 0) {
  250.     printf( "\tP Macro Block Stats:\n");
  251.     printf( "\t%d P Macroblocks\n", stat_a[0].p_mbnum);
  252.     printf( "\tAvg. Size: %d bytes + %d bits\n", 
  253.        stat_a[0].p_mbsize/(8*stat_a[0].p_mbnum), 
  254.        (stat_a[0].p_mbsize/stat_a[0].p_mbnum)%8);
  255.     printf( "\t\tCoded Block Pattern Histogram:\n");
  256.     for (i = 0; i<64; i+= 8) {
  257.       printf( "\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[0].p_mbcbp[i],
  258.          stat_a[0].p_mbcbp[i+1], stat_a[0].p_mbcbp[i+2], stat_a[0].p_mbcbp[i+3], 
  259.          stat_a[0].p_mbcbp[i+4], stat_a[0].p_mbcbp[i+5], stat_a[0].p_mbcbp[i+6], 
  260.          stat_a[0].p_mbcbp[i+7]);
  261.     }
  262.     printf( "\n\t\tNumber of Coefficients/Block Histogram:\n");
  263.     for (i = 0; i<64; i+= 8) {
  264.       printf( "\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[0].p_mbcoeff[i],
  265.          stat_a[0].p_mbcoeff[i+1], stat_a[0].p_mbcoeff[i+2], 
  266.          stat_a[0].p_mbcoeff[i+3], stat_a[0].p_mbcoeff[i+4], 
  267.          stat_a[0].p_mbcoeff[i+5], stat_a[0].p_mbcoeff[i+6], 
  268.          stat_a[0].p_mbcoeff[i+7]);
  269.     }
  270.   }
  271.  
  272.   if (stat_a[0].b_mbnum > 0) {
  273.     printf( "\tB Macro Block Stats:\n");
  274.     printf( "\t%d B Macroblocks\n", stat_a[0].b_mbnum);
  275.     printf( "\tAvg. Size: %d bytes + %d bits\n", 
  276.        stat_a[0].b_mbsize/(8*stat_a[0].b_mbnum), 
  277.        (stat_a[0].b_mbsize/stat_a[0].b_mbnum)%8);
  278.     printf( "\t\tCoded Block Pattern Histogram:\n");
  279.     for (i = 0; i<64; i+= 8) {
  280.       printf( "\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[0].b_mbcbp[i],
  281.          stat_a[0].b_mbcbp[i+1], stat_a[0].b_mbcbp[i+2], stat_a[0].b_mbcbp[i+3], 
  282.          stat_a[0].b_mbcbp[i+4], stat_a[0].b_mbcbp[i+5], stat_a[0].b_mbcbp[i+6], 
  283.          stat_a[0].b_mbcbp[i+7]);
  284.     }
  285.     printf( "\n\t\tNumber of Coefficients/Block Histogram:\n");
  286.     for (i = 0; i<64; i+= 8) {
  287.       printf( "\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[0].b_mbcoeff[i],
  288.          stat_a[0].b_mbcoeff[i+1], stat_a[0].b_mbcoeff[i+2], 
  289.          stat_a[0].b_mbcoeff[i+3], stat_a[0].b_mbcoeff[i+4], 
  290.          stat_a[0].b_mbcoeff[i+5], stat_a[0].b_mbcoeff[i+6], 
  291.          stat_a[0].b_mbcoeff[i+7]);
  292.     }
  293.   }
  294.  
  295.   if (stat_a[0].bi_mbnum > 0) {
  296.     printf( "\tBi Macro Block Stats:\n");
  297.     printf( "\t%d Bi Macroblocks\n", stat_a[0].bi_mbnum);
  298.     printf( "\tAvg. Size: %d bytes + %d bits\n", 
  299.        stat_a[0].bi_mbsize/(8*stat_a[0].bi_mbnum), 
  300.        (stat_a[0].bi_mbsize*stat_a[0].bi_mbnum)%8);
  301.     printf( "\t\tCoded Block Pattern Histogram:\n");
  302.     for (i = 0; i<64; i+= 8) {
  303.       printf( "\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[0].bi_mbcbp[i],
  304.          stat_a[0].bi_mbcbp[i+1], stat_a[0].bi_mbcbp[i+2], stat_a[0].bi_mbcbp[i+3], 
  305.          stat_a[0].bi_mbcbp[i+4], stat_a[0].bi_mbcbp[i+5], stat_a[0].bi_mbcbp[i+6], 
  306.          stat_a[0].bi_mbcbp[i+7]);
  307.     }
  308.     printf( "\n\t\tNumber of Coefficients/Block Histogram:\n");
  309.     for (i = 0; i<64; i+= 8) {
  310.       printf( "\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[0].bi_mbcoeff[i],
  311.          stat_a[0].bi_mbcoeff[i+1], stat_a[0].bi_mbcoeff[i+2], 
  312.          stat_a[0].bi_mbcoeff[i+3], stat_a[0].bi_mbcoeff[i+4], 
  313.          stat_a[0].bi_mbcoeff[i+5], stat_a[0].bi_mbcoeff[i+6], 
  314.          stat_a[0].bi_mbcoeff[i+7]);
  315.     }
  316.   }
  317.  
  318.   printf( "\nTime to Decode: %g secs.\n", stat_a[0].tottime);
  319.   printf( "****************\n");
  320. }
  321.  
  322. void PrintAllStats()
  323. {
  324.   int i, j;
  325.   unsigned int supertot, supernum;
  326.   double supertime;
  327.  
  328.   printf( "\n");
  329.  
  330.   for (i=1; i<4; i++) {
  331.  
  332.     if (stat_a[i].number == 0) continue;
  333.  
  334.     switch (i) {
  335.     case 1:
  336.       printf( "I FRAMES\n");
  337.       break;
  338.     case 2:
  339.       printf( "P FRAMES\n");
  340.       break;
  341.     case 3:
  342.       printf( "B FRAMES\n");
  343.       break;
  344.     }
  345.  
  346.     printf( "Number: %d\n", stat_a[i].number);
  347.     printf( "Avg. Size: %d bytes + %d bits\n", 
  348.        stat_a[i].totsize/(8*stat_a[i].number), (stat_a[i].totsize/stat_a[i].number)%8);
  349.     if (stat_a[i].i_mbnum > 0) {
  350.       printf( "\tI Macro Block Stats:\n");
  351.       printf( "\t%d I Macroblocks\n", stat_a[i].i_mbnum);
  352.       printf( "\tAvg. Size: %d bytes + %d bits\n", 
  353.          stat_a[i].i_mbsize/(8*stat_a[i].i_mbnum),
  354.          (stat_a[i].i_mbsize/stat_a[i].i_mbnum)%8);
  355.       printf( "\t\tCoded Block Pattern Histogram:\n");
  356.       for (j = 0; j<64; j+= 8) {
  357.     printf( "\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[i].i_mbcbp[j],
  358.            stat_a[i].i_mbcbp[j+1], stat_a[i].i_mbcbp[j+2], stat_a[i].i_mbcbp[j+3], 
  359.            stat_a[i].i_mbcbp[j+4], stat_a[i].i_mbcbp[j+5], stat_a[i].i_mbcbp[j+6], 
  360.            stat_a[i].i_mbcbp[j+7]);
  361.       }
  362.       printf( "\n\t\tNumber of Coefficients/Block Histogram:\n");
  363.       for (j = 0; j<64; j+= 8) {
  364.     printf( "\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[i].i_mbcoeff[j],
  365.            stat_a[i].i_mbcoeff[j+1], stat_a[i].i_mbcoeff[j+2], 
  366.            stat_a[i].i_mbcoeff[j+3], stat_a[i].i_mbcoeff[j+4], 
  367.            stat_a[i].i_mbcoeff[j+5], stat_a[i].i_mbcoeff[j+6], 
  368.            stat_a[i].i_mbcoeff[j+7]);
  369.       }
  370.     }
  371.     
  372.     if (stat_a[i].p_mbnum > 0) {
  373.       printf( "\tP Macro Block Stats:\n");
  374.       printf( "\t%d P Macroblocks\n", stat_a[i].p_mbnum);
  375.       printf( "\tAvg. Size: %d bytes + %d bits\n", 
  376.          stat_a[i].p_mbsize/(8*stat_a[i].p_mbnum), 
  377.          (stat_a[i].p_mbsize/stat_a[i].p_mbnum)%8);
  378.       printf( "\t\tCoded Block Pattern Histogram:\n");
  379.       for (j = 0; j<64; j+= 8) {
  380.     printf( "\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[i].p_mbcbp[j],
  381.            stat_a[i].p_mbcbp[j+1], stat_a[i].p_mbcbp[j+2], stat_a[i].p_mbcbp[j+3], 
  382.            stat_a[i].p_mbcbp[j+4], stat_a[i].p_mbcbp[j+5], stat_a[i].p_mbcbp[j+6], 
  383.            stat_a[i].p_mbcbp[j+7]);
  384.       }
  385.       printf( "\n\t\tNumber of Coefficients/Block Histogram:\n");
  386.       for (j = 0; j<64; j+= 8) {
  387.     printf( "\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[i].p_mbcoeff[j],
  388.            stat_a[i].p_mbcoeff[j+1], stat_a[i].p_mbcoeff[j+2], 
  389.            stat_a[i].p_mbcoeff[j+3], stat_a[i].p_mbcoeff[j+4], 
  390.            stat_a[i].p_mbcoeff[j+5], stat_a[i].p_mbcoeff[j+6], 
  391.            stat_a[i].p_mbcoeff[j+7]);
  392.       }
  393.     }
  394.     
  395.     if (stat_a[i].b_mbnum > 0) {
  396.       printf( "\tB Macro Block Stats:\n");
  397.     printf( "\t%d B Macroblocks\n", stat_a[i].b_mbnum);
  398.       printf( "\tAvg. Size: %d bytes + %d bits\n", 
  399.          stat_a[i].b_mbsize/(8*stat_a[i].b_mbnum), 
  400.          (stat_a[i].b_mbsize*stat_a[i].b_mbnum)%8);
  401.       printf( "\t\tCoded Block Pattern Histogram:\n");
  402.       for (j = 0; j<64; j+= 8) {
  403.     printf( "\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[i].b_mbcbp[j],
  404.            stat_a[i].b_mbcbp[j+1], stat_a[i].b_mbcbp[j+2], stat_a[i].b_mbcbp[j+3], 
  405.            stat_a[i].b_mbcbp[j+4], stat_a[i].b_mbcbp[j+5], stat_a[i].b_mbcbp[j+6], 
  406.            stat_a[i].b_mbcbp[j+7]);
  407.       }
  408.       printf( "\n\t\tNumber of Coefficients/Block Histogram:\n");
  409.       for (j = 0; j<64; j+= 8) {
  410.     printf( "\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[i].b_mbcoeff[j],
  411.            stat_a[i].b_mbcoeff[j+1], stat_a[i].b_mbcoeff[j+2], 
  412.            stat_a[i].b_mbcoeff[j+3], stat_a[i].b_mbcoeff[j+4], 
  413.            stat_a[i].b_mbcoeff[j+5], stat_a[i].b_mbcoeff[j+6], 
  414.            stat_a[i].b_mbcoeff[j+7]);
  415.       }
  416.     }
  417.     
  418.     if (stat_a[i].bi_mbnum > 0) {
  419.       printf( "\tBi Macro Block Stats:\n");
  420.       printf( "\t%d Bi Macroblocks\n", stat_a[i].bi_mbnum);
  421.       printf( "\tAvg. Size: %d bytes + %d bits\n", 
  422.          stat_a[i].bi_mbsize/(8*stat_a[i].bi_mbnum), 
  423.          (stat_a[i].bi_mbsize*stat_a[i].bi_mbnum)%8);
  424.       printf( "\t\tCoded Block Pattern Histogram:\n");
  425.       for (j = 0; j<64; j+= 8) {
  426.     printf( "\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[i].bi_mbcbp[j],
  427.            stat_a[i].bi_mbcbp[j+1], stat_a[i].bi_mbcbp[j+2], stat_a[i].bi_mbcbp[j+3], 
  428.            stat_a[i].bi_mbcbp[j+4], stat_a[i].bi_mbcbp[j+5], stat_a[i].bi_mbcbp[j+6], 
  429.            stat_a[i].bi_mbcbp[j+7]);
  430.       }
  431.       printf( "\n\t\tNumber of Coefficients/Block Histogram:\n");
  432.       for (j = 0; j<64; j+= 8) {
  433.     printf( "\t%.6d %.6d %.6d %.6d %.6d %.6d %.6d %.6d\n", stat_a[i].bi_mbcoeff[j],
  434.            stat_a[i].bi_mbcoeff[j+1], stat_a[i].bi_mbcoeff[j+2], 
  435.            stat_a[i].bi_mbcoeff[j+3], stat_a[i].bi_mbcoeff[j+4], 
  436.            stat_a[i].bi_mbcoeff[j+5], stat_a[i].bi_mbcoeff[j+6], 
  437.            stat_a[i].bi_mbcoeff[j+7]);
  438.       }
  439.     }
  440.     
  441.     printf( "\nAvg. Time to Decode: %f secs.\n", 
  442.        (stat_a[i].tottime/((double) stat_a[i].number)));
  443.     printf( "\n");
  444.     printf( "*************************\n\n");
  445.   }
  446.  
  447.   supertot = stat_a[1].totsize + stat_a[2].totsize + stat_a[3].totsize;
  448.   supernum = stat_a[1].number + stat_a[2].number + stat_a[3].number;
  449.   supertime = stat_a[1].tottime + stat_a[2].tottime + stat_a[3].tottime;
  450.  
  451.   printf( "Total Number of Frames: %d\n", supernum);
  452.   printf( "Avg Frame Size: %d bytes %d bits\n",
  453.      supertot/(8*supernum), (supertot/supernum)%8);
  454.   printf( "Total Time Decoding: %g secs.\n", supertime);
  455.   printf( "Avg Decoding Time/Frame: %g secs.\n", supertime/((double) supernum));
  456.   printf( "Avg Decoding Frames/Sec: %g secs.\n", ((double) supernum)/supertime);
  457.   printf( "\n");
  458.  
  459.   printf("Cache Hits/Miss\n");
  460.   for (i=0; i<8; i++) {
  461.     printf("%.6d/%.6d\t%.6d/%.6d\t%.6d/%.6d\t%.6d/%.6d\n", 
  462.        cacheHit[i][0], cacheMiss[i][0], cacheHit[i][1], cacheMiss[i][1], 
  463.        cacheHit[i][2], cacheMiss[i][2], cacheHit[i][3], cacheMiss[i][3]);
  464.     printf("%.6d/%.6d\t%.6d/%.6d\t%.6d/%.6d\t%.6d/%.6d\n", 
  465.        cacheHit[i][4], cacheMiss[i][4], cacheHit[i][5], cacheMiss[i][5], 
  466.        cacheHit[i][6], cacheMiss[i][6],  cacheHit[i][7], cacheMiss[i][7]);
  467.   }
  468.  
  469. }
  470.  
  471. static void CollectStats()
  472. {
  473.   int i, j;
  474.  
  475.   i = stat_a[0].frametype;
  476.  
  477.   stat_a[i].totsize += stat_a[0].totsize;
  478.   stat_a[i].number += stat_a[0].number;
  479.   stat_a[i].i_mbsize += stat_a[0].i_mbsize;
  480.   stat_a[i].p_mbsize += stat_a[0].p_mbsize;
  481.   stat_a[i].b_mbsize += stat_a[0].b_mbsize;
  482.   stat_a[i].bi_mbsize += stat_a[0].bi_mbsize;
  483.   stat_a[i].i_mbnum += stat_a[0].i_mbnum;
  484.   stat_a[i].p_mbnum += stat_a[0].p_mbnum;
  485.   stat_a[i].b_mbnum += stat_a[0].b_mbnum;
  486.   stat_a[i].bi_mbnum += stat_a[0].bi_mbnum;
  487.   
  488.   for (j=0; j<64; j++) {
  489.     
  490.     stat_a[i].i_mbcbp[j] +=   stat_a[0].i_mbcbp[j];
  491.     stat_a[i].p_mbcbp[j] +=   stat_a[0].p_mbcbp[j];
  492.     stat_a[i].b_mbcbp[j] +=   stat_a[0].b_mbcbp[j];
  493.     stat_a[i].bi_mbcbp[j] +=   stat_a[0].bi_mbcbp[j];
  494.     stat_a[i].i_mbcoeff[j] +=   stat_a[0].i_mbcoeff[j];
  495.     stat_a[i].p_mbcoeff[j] +=   stat_a[0].p_mbcoeff[j];
  496.     stat_a[i].b_mbcoeff[j] +=   stat_a[0].b_mbcoeff[j];
  497.     stat_a[i].bi_mbcoeff[j] +=   stat_a[0].bi_mbcoeff[j];
  498.   }
  499.  
  500.   stat_a[i].tottime += stat_a[0].tottime;
  501.  
  502.   init_stat_struct(&(stat_a[0]));
  503. }
  504.  
  505. unsigned  int bitCountRead()
  506. {
  507.   return bitCount;
  508. }
  509.  
  510. StartTime()
  511. {
  512.   stat_a[0].tottime = ReadSysClock();
  513. }
  514.  
  515. EndTime()
  516. {
  517.   stat_a[0].tottime = ReadSysClock() - stat_a[0].tottime;
  518. }
  519.  
  520. #endif
  521.  
  522. double realTimeStart;
  523. int totNumFrames = 0;
  524.  
  525. double
  526. ReadSysClock ()
  527. {
  528.     struct timeval tv;
  529.     (void) gettimeofday(&tv, NULL);
  530.     return (tv.tv_sec + tv.tv_usec / 1000000.0);
  531. }
  532.  
  533. void PrintTimeInfo() 
  534. {
  535.   double spent;
  536.  
  537.   spent = ReadSysClock()-realTimeStart;
  538.  
  539.   printf( "\nReal Time Spent (After Initializations): %f secs.\n", spent);
  540.   printf( "Avg. Frames/Sec: %f\n", ((double) totNumFrames) / spent);
  541. }
  542.  
  543.  
  544. /*
  545.  *--------------------------------------------------------------
  546.  *
  547.  * NewVidStream --
  548.  *
  549.  *    Allocates and initializes a VidStream structure. Takes
  550.  *      as parameter requested size for buffer length.
  551.  *
  552.  * Results:
  553.  *    A pointer to the new VidStream structure.
  554.  *
  555.  * Side effects:
  556.  *      None.
  557.  *
  558.  *--------------------------------------------------------------
  559.  */
  560.  
  561. VidStream *NewVidStream(bufLength)
  562.      int bufLength;
  563. {
  564.   int i, j;
  565.   VidStream *new;
  566.   static unsigned char  default_intra_matrix[64] = {
  567.     8, 16, 19, 22, 26, 27, 29, 34,
  568.     16, 16, 22, 24, 27, 29, 34, 37,
  569.     19, 22, 26, 27, 29, 34, 34, 38,
  570.     22, 22, 26, 27, 29, 34, 37, 40,
  571.     22, 26, 27, 29, 32, 35, 40, 48,
  572.     26, 27, 29, 32, 35, 40, 48, 58,
  573.     26, 27, 29, 34, 38, 46, 56, 69,
  574.     27, 29, 35, 38, 46, 56, 69, 83 };
  575.  
  576.   /* Check for legal buffer length. */
  577.  
  578.   if (bufLength < 4)
  579.     return NULL;
  580.  
  581.   /* Make buffer length multiple of 4. */
  582.  
  583.   bufLength = (bufLength + 3) >> 2;
  584.  
  585.   /* Allocate memory for new structure. */
  586.  
  587.   new = (VidStream *) malloc(sizeof(VidStream));
  588.  
  589.   /* Initialize pointers to extension and user data. */
  590.  
  591.   new->group.ext_data = new->group.user_data = 
  592.     new->picture.extra_info = new->picture.user_data =
  593.       new->picture.ext_data = new->slice.extra_info =
  594.     new->ext_data = new->user_data = NULL;
  595.  
  596.   /* Copy default intra matrix. */
  597.  
  598.   for (i=0; i<8; i++) {
  599.     for (j = 0; j<8; j++) {
  600.       new->intra_quant_matrix[j][i] = default_intra_matrix[i*8+j];
  601.     }
  602.   }
  603.  
  604.   /* Initialize crop table. */
  605.  
  606.   for (i=-MAX_NEG_CROP; i< NUM_CROP_ENTRIES - MAX_NEG_CROP; i++) {
  607.       if (i <= 0) {
  608.       cropTbl[i+MAX_NEG_CROP] = 0;
  609.       } else if (i >= 255) {
  610.       cropTbl[i+MAX_NEG_CROP] = 255;
  611.       } else {
  612.       cropTbl[i+MAX_NEG_CROP] = i;
  613.       }
  614.   }
  615.  
  616.   /* Initialize non intra quantization matrix. */
  617.  
  618.   for (i=0; i<8; i++) {
  619.     for (j=0; j<8; j++) {
  620.       new->non_intra_quant_matrix[j][i] = 16;
  621.     }
  622.   }
  623.  
  624.   /* Initialize pointers to image spaces. */
  625.  
  626.   new->current = new->past = new->future = NULL;
  627.   for (i=0; i<RING_BUF_SIZE; i++) {
  628.     new->ring[i] = NULL;
  629.   }
  630.  
  631.   /* Create buffer. */
  632.  
  633.   new->buf_start = (unsigned int *) malloc(bufLength*4);
  634.  
  635.   /* Set max_buf_length to one less than actual length to
  636.      deal with messy data without proper seq. end codes. 
  637.   */
  638.  
  639.   new->max_buf_length = bufLength - 1;
  640.  
  641.   /* Initialize bitstream i/o fields. */
  642.  
  643.   new->bit_offset = 0;
  644.   new->buf_length = 0;
  645.   new->buffer = new->buf_start;
  646.  
  647.  
  648.   /* Return structure. */
  649.  
  650.   return new;
  651. }
  652.  
  653.  
  654. /*
  655.  *--------------------------------------------------------------
  656.  *
  657.  * DestroyVidStream --
  658.  *
  659.  *    Deallocates a VidStream structure.
  660.  *
  661.  * Results:
  662.  *      None.
  663.  *
  664.  * Side effects:
  665.  *    None.
  666.  *
  667.  *--------------------------------------------------------------
  668.  */
  669. void DestroyVidStream(astream)
  670.      VidStream *astream;
  671. {
  672.   int i;
  673.  
  674.   if (astream->ext_data != NULL)
  675.     free(astream->ext_data);
  676.  
  677.   if (astream->user_data != NULL)
  678.     free(astream->user_data);
  679.  
  680.   if (astream->group.ext_data != NULL)
  681.     free(astream->group.ext_data);
  682.  
  683.   if (astream->group.user_data != NULL)
  684.     free(astream->group.user_data);
  685.  
  686.   if (astream->picture.extra_info != NULL)
  687.     free(astream->picture.extra_info);
  688.  
  689.   if (astream->picture.ext_data != NULL)
  690.     free(astream->picture.ext_data);
  691.  
  692.   if (astream->picture.user_data != NULL)
  693.     free(astream->picture.user_data);
  694.  
  695.   if (astream->slice.extra_info != NULL)
  696.     free(astream->slice.extra_info);
  697.  
  698.   if (astream->buf_start != NULL)
  699.     free(astream->buf_start);
  700.   
  701.   for (i=0; i<RING_BUF_SIZE; i++) {
  702.     if (astream->ring[i] != NULL) {
  703.       DestroyPictImage(astream->ring[i]);
  704.     }
  705.   }
  706.  
  707.   free((char *) astream);
  708. }
  709.  
  710.   
  711.  
  712. /*
  713.  *--------------------------------------------------------------
  714.  *
  715.  * NewPictImage --
  716.  *
  717.  *    Allocates and initializes a PictImage structure.
  718.  *      The width and height of the image space are passed in
  719.  *      as parameters.
  720.  *
  721.  * Results:
  722.  *    A pointer to the new PictImage structure.
  723.  *
  724.  * Side effects:
  725.  *    None.
  726.  *
  727.  *--------------------------------------------------------------
  728.  */
  729.  
  730. PictImage *NewPictImage(width, height)
  731.      int width, height;
  732. {
  733.   PictImage *new;
  734.  
  735.   /* Allocate memory space for new structure. */
  736.  
  737.   new = (PictImage *) malloc(sizeof(PictImage));
  738.  
  739.  
  740.   /* Allocate memory for image spaces. */
  741.  
  742. #ifdef SH_MEM
  743.   new->ximage = NULL;
  744.  
  745.   if (shmemFlag) {
  746.     Visual *fc_visual;
  747.     int depth;
  748.     Visual *FindFullColorVisual();
  749.  
  750.     if (ditherType == Twox2_DITHER) {
  751.       new->ximage = XShmCreateImage(display, None, 8, ZPixmap, NULL,
  752.                 &(new->shminfo), width * 2, height *2);
  753.     } else if (ditherType == FULL_COLOR_DITHER) {
  754.       fc_visual = FindFullColorVisual(display, &depth);
  755.       new->ximage = XShmCreateImage (display, fc_visual, depth, ZPixmap,
  756.                  NULL, &(new->shminfo), width, height);
  757.     } else if (ditherType == MONO_DITHER || ditherType == MONO_THRESHOLD) {
  758.       new->ximage = XShmCreateImage (display, None, 1, XYBitmap,
  759.                  NULL, &(new->shminfo), width, height);
  760.     } else {
  761.       new->ximage = XShmCreateImage(display, None, 8, ZPixmap, NULL,
  762.                 &(new->shminfo), width, height);
  763.     }
  764.  
  765.     /* If no go, then revert to normal Xlib calls. */
  766.  
  767.     if (new->ximage == NULL) {
  768.       shmemFlag = 0;
  769.       fprintf(stderr, "Shared memory error, disabling.\n");
  770.       fprintf(stderr, "Ximage error.\n");
  771.       goto shmemerror;
  772.     }
  773.  
  774.     /* Success here, continue. */
  775.  
  776.     new->shminfo.shmid = shmget(IPC_PRIVATE, (new->ximage->bytes_per_line * 
  777.                      new->ximage->height),
  778.                IPC_CREAT|0777);
  779.     
  780.     if (new->shminfo.shmid < 0) {
  781.       XDestroyImage(new->ximage);
  782.       new->ximage = NULL;
  783.       shmemFlag = 0;
  784.       fprintf(stderr, "Shared memory error, disabling.\n");
  785.       fprintf(stderr, "Seg. id. error.\n");
  786.       goto shmemerror;
  787.     }
  788.  
  789.     new->shminfo.shmaddr = (char *) shmat(new->shminfo.shmid, 0, 0);
  790.     if (new->shminfo.shmaddr == ((char *) -1)) {
  791.       XDestroyImage(new->ximage);
  792.       new->ximage = NULL;
  793.       shmemFlag = 0;
  794.       fprintf(stderr, "Shared memory error, disabling.\n");
  795.       fprintf(stderr, "Address error.\n");
  796.       goto shmemerror;
  797.     }
  798.     new->ximage->data = new->shminfo.shmaddr;
  799.     new->display = (unsigned char *) new->ximage->data;
  800.     new->shminfo.readOnly = False;
  801.  
  802.     XShmAttach(display, &(new->shminfo));
  803.     XSync(display, False);
  804.  
  805.     if (gXErrorFlag) { 
  806.       /* Ultimate failure here. */
  807.       XDestroyImage(new->ximage);
  808.       new->ximage = NULL;
  809.       shmemFlag = 0;
  810.       fprintf(stderr, "Shared memory error, disabling.\n");
  811.       gXErrorFlag = 0;
  812.       goto shmemerror;
  813.     }
  814.  
  815.     fprintf(stderr, "Sharing memory.\n");
  816.   }
  817.   else 
  818. #endif
  819.     {
  820.     shmemerror:
  821.   
  822.     if ((ditherType == Twox2_DITHER) || (ditherType == FULL_COLOR_DITHER)) {
  823.       new->display = (unsigned char *) malloc(width*height*4);
  824.     } else {
  825.       new->display = (unsigned char *) malloc(width*height);
  826.     }
  827.   }
  828.  
  829.   new->luminance = (unsigned char *) malloc(width*height);
  830.   new->Cr = (unsigned char *) malloc(width*height/4);
  831.   new->Cb = (unsigned char *) malloc(width*height/4);
  832.  
  833.   /* Reset locked flag. */
  834.  
  835.   new->locked = 0;
  836.  
  837.   /* Return pointer to new structure. */
  838.  
  839.   return new;
  840. }
  841.  
  842.  
  843. /*
  844.  *--------------------------------------------------------------
  845.  *
  846.  * DestroyPictImage --
  847.  *
  848.  *    Deallocates a PictImage structure.
  849.  *
  850.  * Results:
  851.  *      None.
  852.  *
  853.  * Side effects:
  854.  *    None.
  855.  *
  856.  *--------------------------------------------------------------
  857.  */
  858. void DestroyPictImage(apictimage)
  859.      PictImage *apictimage;
  860. {
  861.   if (apictimage->luminance != NULL) {
  862.     free(apictimage->luminance);
  863.   }
  864.   if (apictimage->Cr != NULL) {
  865.     free(apictimage->Cr);
  866.   }
  867.   if (apictimage->Cb != NULL) {
  868.     free(apictimage->Cb);
  869.   }
  870.  
  871. #ifdef SH_MEM
  872.   if (apictimage->ximage != NULL) {
  873.     XShmDetach(display, &(apictimage->shminfo));
  874.     XDestroyImage(apictimage->ximage);
  875.     shmdt(apictimage->shminfo.shmaddr);
  876.     shmctl(apictimage->shminfo.shmid, IPC_RMID, 0);
  877.     apictimage->ximage = NULL;
  878.     apictimage->display = NULL;
  879.   }
  880. #endif
  881.  
  882.   if (apictimage->display != NULL) {
  883.     free(apictimage->display);
  884.   }
  885.   
  886. }
  887.  
  888.  
  889. /*
  890.  *--------------------------------------------------------------
  891.  *
  892.  * mpegVidRsrc --
  893.  *
  894.  *      Parses bit stream until MB_QUANTUM number of 
  895.  *      macroblocks have been decoded or current slice or
  896.  *      picture ends, whichever comes first. If the start
  897.  *      of a frame is encountered, the frame is time stamped
  898.  *      with the value passed in time_stamp. If the value
  899.  *      passed in buffer is not null, the video stream buffer
  900.  *      is set to buffer and the length of the buffer is
  901.  *      expected in value passed in through length. The current
  902.  *      video stream is set to vid_stream. If vid_stream
  903.  *      is passed as NULL, a new VidStream structure is created
  904.  *      and initialized and used as the current video stream. 
  905.  *
  906.  * Results:
  907.  *      A pointer to the video stream structure used.
  908.  *
  909.  * Side effects:
  910.  *      Bit stream is irreversibly parsed. If a picture is completed,
  911.  *      a function is called to display the frame at the correct time.
  912.  *
  913.  *--------------------------------------------------------------
  914.  */
  915.  
  916. VidStream *mpegVidRsrc(time_stamp, vid_stream)
  917. TimeStamp time_stamp;
  918. VidStream *vid_stream;
  919. {
  920.   static int first = 1;
  921.   unsigned  int data;
  922.   int i, status;
  923.  
  924.   /* If vid_stream is null, create new VidStream structure. */
  925.  
  926.   if (vid_stream == NULL) {
  927.     return NULL;
  928.   }
  929.  
  930.   /* Set global curVidStream to vid_stream. Necessary because bit i/o
  931.      use curVidStream and are not passed vid_stream. Also set global 
  932.      bitstream parameters.
  933.   */
  934.  
  935.   curVidStream = vid_stream;
  936.   curBits = *curVidStream->buffer;
  937.   bitOffset = curVidStream->bit_offset;
  938.   bufLength = curVidStream->buf_length;
  939.   bitBuffer = curVidStream->buffer;
  940.  
  941.   /* If called for the first time, find start code, make sure it is a
  942.      sequence start code. 
  943.   */
  944.  
  945.   if (first) {
  946.     next_start_code();
  947.     show_bits32(&data);
  948.     if (data != SEQ_START_CODE) {
  949.       fprintf(stderr, "This is not an MPEG stream.");
  950.       DestroyVidStream(curVidStream);
  951.       exit(1);
  952.     }
  953.     first = 0;
  954.   }
  955.  
  956.   /* Get next 32 bits (size of start codes). */
  957.  
  958.   show_bits32(&data);
  959.  
  960.   /* Process according to start code (or parse macroblock if not a 
  961.      start code at all. 
  962.   */
  963.  
  964.   switch (data) {
  965.  
  966.   case SEQ_END_CODE:
  967.  
  968.     /*Sequence done. Do the right thing. For right now, exit. */
  969.  
  970.     fprintf(stderr, "\nDone!\n");
  971. #ifdef ANALYSIS
  972.     PrintAllStats();
  973. #endif
  974.     PrintTimeInfo();
  975.  
  976.     if (loopFlag) longjmp(env, 1);
  977.  
  978.     DestroyVidStream(curVidStream);
  979.     exit();
  980.     break;
  981.  
  982.   case SEQ_START_CODE:
  983.  
  984.     /* Sequence start code. Parse sequence header. */
  985.  
  986.     if (ParseSeqHead(vid_stream) != PARSE_OK)
  987.       goto error;
  988.  
  989.     /* Return after sequence start code so that application above can
  990.        use info in header. 
  991.     */
  992.  
  993.     goto done;
  994.  
  995.   case GOP_START_CODE:
  996.  
  997.     /* Group of Pictures start code. Parse gop header. */
  998.  
  999.     if (ParseGOP(vid_stream) != PARSE_OK)
  1000.       goto error;
  1001.  
  1002.   case PICTURE_START_CODE:
  1003.  
  1004.     /* Picture start code. Parse picture header and first slice header. */
  1005.  
  1006.     status = ParsePicture(vid_stream, time_stamp);
  1007.  
  1008.     if (status == SKIP_PICTURE) {
  1009.       next_start_code();
  1010.       fprintf(stderr, "Skipping picture...");
  1011.       while (!next_bits(32, PICTURE_START_CODE)) {
  1012.         if (next_bits(32, GOP_START_CODE)) break;
  1013.         else if (next_bits(32, SEQ_END_CODE)) break;
  1014.         flush_bits(24);
  1015.         next_start_code();
  1016.       }
  1017.       fprintf(stderr, "Done.\n");
  1018.       goto done;
  1019.     }
  1020.     else if (status != PARSE_OK)
  1021.       goto error;
  1022.  
  1023.     if (ParseSlice(vid_stream) != PARSE_OK)
  1024.       goto error;
  1025.     break;
  1026.  
  1027.   default:
  1028.  
  1029.     /* Check for slice start code. */
  1030.  
  1031.     if ((data >= SLICE_MIN_START_CODE) && (data <= SLICE_MAX_START_CODE)) {
  1032.  
  1033.       /* Slice start code. Parse slice header. */
  1034.  
  1035.       if (ParseSlice(vid_stream) != PARSE_OK)
  1036.         goto error;
  1037.     }
  1038.  
  1039.     break;
  1040.   }
  1041.  
  1042.   /* Parse next MB_QUANTUM macroblocks. */
  1043.  
  1044.   for(i=0; i< MB_QUANTUM; i++) {
  1045.  
  1046.     /* Check to see if actually a startcode and not a macroblock. */
  1047.  
  1048.     if (!next_bits(23, 0x00000000)) {
  1049.  
  1050.       /* Not start code. Parse Macroblock. */
  1051.  
  1052.       if (ParseMacroBlock(vid_stream) != PARSE_OK)
  1053.         goto error;
  1054.  
  1055. #ifdef ANALYSIS
  1056.       if (showmb_flag) {
  1057.     DoDitherImage(vid_stream->current->luminance, vid_stream->current->Cr,
  1058.               vid_stream->current->Cb, vid_stream->current->display,
  1059.               vid_stream->mb_height*16, vid_stream->mb_width*16);
  1060.     ExecuteDisplay(vid_stream);
  1061.       }
  1062. #endif
  1063.  
  1064.     }
  1065.     else {
  1066.  
  1067.       /* Not macroblock, actually start code. Get start code. */
  1068.  
  1069.       next_start_code();
  1070.       show_bits32(&data);
  1071.  
  1072.       /* If start code is outside range of slice start codes, frame
  1073.          is complete, display frame. 
  1074.       */
  1075.  
  1076.       if ((data < SLICE_MIN_START_CODE) || (data > SLICE_MAX_START_CODE)) {
  1077.  
  1078. #ifdef ANALYSIS
  1079.     EndTime();
  1080.     stat_a[0].totsize += bitCountRead() - pictureSizeCount;
  1081.         if (showEachFlag) {
  1082.       PrintOneStat();
  1083.     };
  1084.  
  1085.     CollectStats();
  1086. #endif
  1087.  
  1088.         DoPictureDisplay(vid_stream);
  1089.       }
  1090.       break;
  1091.     }    
  1092.   }
  1093.   
  1094.   /* Return pointer to video stream structure. */
  1095.  
  1096.   goto done;
  1097.  
  1098.  error:
  1099.   fprintf(stderr, "Error!!!!\n");
  1100.   next_start_code();
  1101.   goto done;
  1102.  
  1103.  done:
  1104.   
  1105.   /* Copy global bit i/o variables back into vid_stream. */
  1106.  
  1107.   vid_stream->buffer = bitBuffer;
  1108.   vid_stream->buf_length = bufLength;
  1109.   vid_stream->bit_offset = bitOffset;
  1110.  
  1111.   return vid_stream;
  1112.  
  1113. }
  1114.  
  1115.  
  1116. /*
  1117.  *--------------------------------------------------------------
  1118.  *
  1119.  * ParseSeqHead --
  1120.  *
  1121.  *      Assumes bit stream is at the begining of the sequence
  1122.  *      header start code. Parses off the sequence header.
  1123.  *
  1124.  * Results:
  1125.  *      Fills the vid_stream structure with values derived and
  1126.  *      decoded from the sequence header. Allocates the pict image
  1127.  *      structures based on the dimensions of the image space
  1128.  *      found in the sequence header.
  1129.  *
  1130.  * Side effects:
  1131.  *      Bit stream irreversibly parsed off.
  1132.  *
  1133.  *--------------------------------------------------------------
  1134.  */
  1135.  
  1136. static int
  1137. ParseSeqHead(vid_stream)
  1138. VidStream *vid_stream;
  1139. {
  1140.  
  1141.   unsigned  int data;
  1142.   int i;
  1143.  
  1144.   /* Flush off sequence start code. */
  1145.  
  1146.   flush_bits(32);
  1147.  
  1148.   /* Get horizontal size of image space. */
  1149.  
  1150.   get_bits12(&data);
  1151.   vid_stream->h_size = data;
  1152.  
  1153.   /* Get vertical size of image space. */
  1154.  
  1155.   get_bits12(&data);
  1156.   vid_stream->v_size = data;
  1157.  
  1158.   /* Calculate macroblock width and height of image space. */
  1159.  
  1160.   vid_stream->mb_width = (vid_stream->h_size+15)/16;
  1161.   vid_stream->mb_height = (vid_stream->v_size+15)/16;
  1162.  
  1163.   /* Initialize ring buffer of pict images now that dimensions
  1164.      of image space are known.
  1165.   */
  1166.  
  1167. #ifdef SH_MEM
  1168.   if (display != NULL) {
  1169.       InstallXErrorHandler();
  1170.   }
  1171. #endif
  1172.  
  1173.   if (vid_stream->ring[0] == NULL) {
  1174.     for(i=0; i<RING_BUF_SIZE; i++) {
  1175.       vid_stream->ring[i] = NewPictImage(vid_stream->mb_width*16, 
  1176.                                          vid_stream->mb_height*16);
  1177.     }
  1178.   }
  1179.  
  1180. #ifdef SH_MEM
  1181.   if (display != NULL) {
  1182.       DeInstallXErrorHandler();
  1183.   }
  1184. #endif
  1185.  
  1186.   /* Parse of aspect ratio code. */
  1187.  
  1188.   get_bits4(&data);
  1189.   vid_stream->aspect_ratio = (unsigned char) data;
  1190.  
  1191.   /* Parse off picture rate code. */
  1192.  
  1193.   get_bits4(&data);
  1194.   vid_stream->picture_rate = (unsigned char) data;
  1195.  
  1196.   /* Parse off bit rate. */
  1197.  
  1198.   get_bits18(&data);
  1199.   vid_stream->bit_rate = data;
  1200.  
  1201.   /* Flush marker bit. */
  1202.  
  1203.   flush_bits(1);
  1204.  
  1205.   /* Parse off vbv buffer size. */
  1206.  
  1207.   get_bits10(&data);
  1208.   vid_stream->vbv_buffer_size = data;
  1209.  
  1210.   /* Parse off contrained parameter flag. */
  1211.  
  1212.   get_bits1(&data);
  1213.   if (data) {
  1214.     vid_stream->const_param_flag = TRUE;
  1215.   } else vid_stream->const_param_flag = FALSE;
  1216.  
  1217.   /* If intra_quant_matrix_flag set, parse off intra quant matrix 
  1218.      values.
  1219.   */
  1220.  
  1221.   get_bits1(&data);
  1222.   if (data) {
  1223.     for(i=0; i<64; i++) {
  1224.       get_bits8(&data);
  1225.  
  1226.       vid_stream->intra_quant_matrix[zigzag[i][1]][zigzag[i][0]] = 
  1227.         (unsigned char) data;
  1228.     }
  1229.   }
  1230.  
  1231.   /* If non intra quant matrix flag set, parse off non intra quant matrix
  1232.      values.
  1233.   */
  1234.  
  1235.   get_bits1(&data);
  1236.   if (data) {
  1237.     for (i=0; i<64; i++) {
  1238.       get_bits8(&data);
  1239.  
  1240.       vid_stream->non_intra_quant_matrix[zigzag[i][1]][zigzag[i][0]] =
  1241.         (unsigned char) data;
  1242.     }
  1243.   }
  1244.  
  1245.   /* Go to next start code. */
  1246.  
  1247.   next_start_code();
  1248.  
  1249.   /* If next start code is extension start code, parse off extension
  1250.      data. 
  1251.   */
  1252.  
  1253.   if (next_bits(32, EXT_START_CODE)) {
  1254.     flush_bits(32);
  1255.     if (vid_stream->ext_data != NULL) {
  1256.       free(vid_stream->ext_data);
  1257.       vid_stream->ext_data = NULL;
  1258.     }
  1259.     vid_stream->ext_data = get_ext_data();
  1260.   }
  1261.  
  1262.   /* If next start code is user start code, parse off user data. */
  1263.  
  1264.   if (next_bits(32, USER_START_CODE)) {
  1265.     flush_bits(32);
  1266.     if (vid_stream->user_data != NULL) {
  1267.       free(vid_stream->user_data);
  1268.       vid_stream->user_data = NULL;
  1269.     }
  1270.     vid_stream->user_data = get_ext_data();
  1271.   }
  1272.  
  1273.   return PARSE_OK;
  1274. }
  1275.  
  1276.  
  1277. /*
  1278.  *--------------------------------------------------------------
  1279.  *
  1280.  * ParseGOP --
  1281.  *
  1282.  *      Parses of group of pictures header from bit stream
  1283.  *      associated with vid_stream.
  1284.  *
  1285.  * Results:
  1286.  *      Values in gop header placed into video stream structure.
  1287.  *
  1288.  * Side effects:
  1289.  *      Bit stream irreversibly parsed.
  1290.  *
  1291.  *--------------------------------------------------------------
  1292.  */
  1293.  
  1294. static int
  1295. ParseGOP(vid_stream)
  1296. VidStream *vid_stream;
  1297. {
  1298.   unsigned  int data;
  1299.  
  1300.   /* Flush group of pictures start code. WWWWWWOOOOOOOSSSSSSHHHHH!!! */
  1301.  
  1302.   flush_bits(32);
  1303.  
  1304.   /* Parse off drop frame flag. */
  1305.  
  1306.   get_bits1(&data);
  1307.   if(data) {
  1308.     vid_stream->group.drop_flag = TRUE;
  1309.   } else vid_stream->group.drop_flag = FALSE;
  1310.  
  1311.   /* Parse off hour component of time code. */
  1312.  
  1313.   get_bits5(&data);
  1314.   vid_stream->group.tc_hours = data;
  1315.  
  1316.   /* Parse off minute component of time code. */
  1317.  
  1318.   get_bits6(&data);
  1319.   vid_stream->group.tc_minutes = data;
  1320.  
  1321.   /* Flush marker bit. */
  1322.  
  1323.   flush_bits(1);
  1324.  
  1325.   /* Parse off second component of time code. */
  1326.  
  1327.   get_bits6(&data);
  1328.   vid_stream->group.tc_seconds = data;
  1329.  
  1330.   /* Parse off picture count component of time code. */
  1331.  
  1332.   get_bits6(&data);
  1333.   vid_stream->group.tc_pictures = data;
  1334.  
  1335.   /* Parse off closed gop and broken link flags. */
  1336.  
  1337.   get_bits2(&data);
  1338.   if (data > 1) {
  1339.     vid_stream->group.closed_gop = TRUE;
  1340.     if (data > 2) {
  1341.       vid_stream->group.broken_link = TRUE;
  1342.     } else vid_stream->group.broken_link = FALSE;
  1343.   } else {
  1344.     vid_stream->group.closed_gop = FALSE;
  1345.     if (data) {
  1346.       vid_stream->group.broken_link = TRUE;
  1347.     } else vid_stream->group.broken_link = FALSE;
  1348.   }
  1349.  
  1350.   /* Goto next start code. */
  1351.  
  1352.   next_start_code();
  1353.  
  1354.   /* If next start code is extension data, parse off extension data. */
  1355.  
  1356.   if (next_bits(32, EXT_START_CODE)) {
  1357.     flush_bits(32);
  1358.     if (vid_stream->group.ext_data != NULL) {
  1359.       free(vid_stream->group.ext_data);
  1360.       vid_stream->group.ext_data = NULL;
  1361.     }
  1362.     vid_stream->group.ext_data = get_ext_data();
  1363.   }
  1364.  
  1365.   /* If next start code is user data, parse off user data. */
  1366.  
  1367.   if (next_bits(32, USER_START_CODE)) {
  1368.     flush_bits(32);
  1369.     if (vid_stream->group.user_data != NULL) {
  1370.       free(vid_stream->group.user_data);
  1371.       vid_stream->group.user_data = NULL;
  1372.     }
  1373.     vid_stream->group.user_data = get_ext_data();
  1374.   }
  1375.  
  1376.   return PARSE_OK;
  1377. }
  1378.  
  1379.  
  1380. /*
  1381.  *--------------------------------------------------------------
  1382.  *
  1383.  * ParsePicture --
  1384.  *
  1385.  *      Parses picture header. Marks picture to be presented
  1386.  *      at particular time given a time stamp.
  1387.  *
  1388.  * Results:
  1389.  *      Values from picture header put into video stream structure.
  1390.  *
  1391.  * Side effects:
  1392.  *      Bit stream irreversibly parsed.
  1393.  *
  1394.  *--------------------------------------------------------------
  1395.  */
  1396.  
  1397. static int
  1398. ParsePicture(vid_stream, time_stamp)
  1399. VidStream *vid_stream;
  1400. TimeStamp time_stamp;
  1401. {
  1402.   unsigned  int data;
  1403.   int i;
  1404.  
  1405.   /* Flush header start code. */
  1406.   flush_bits(32);
  1407.  
  1408.   /* Parse off temporal reference. */
  1409.   get_bits10(&data);
  1410.   vid_stream->picture.temp_ref = data;
  1411.  
  1412.   /* Parse of picture type. */
  1413.   get_bits3(&data);
  1414.   vid_stream->picture.code_type = data;
  1415.  
  1416.   if ((vid_stream->picture.code_type == B_TYPE) && (No_B_Flag || 
  1417.                                                     (vid_stream->past == NULL) || 
  1418.                                                     (vid_stream->future == NULL)))
  1419.     return SKIP_PICTURE;
  1420.  
  1421.   if ((vid_stream->picture.code_type == P_TYPE) && (No_P_Flag ||
  1422.                                                     (vid_stream->future == NULL))) 
  1423.     return SKIP_PICTURE;
  1424.  
  1425. #ifdef ANALYSIS
  1426.   StartTime();
  1427.   stat_a[0].frametype = vid_stream->picture.code_type;
  1428.   stat_a[0].number = 1;
  1429.   stat_a[0].totsize = 45;
  1430.   pictureSizeCount = bitCountRead();
  1431. #endif
  1432.  
  1433.   /* Parse off vbv buffer delay value. */
  1434.   get_bits16(&data);
  1435.   vid_stream->picture.vbv_delay = data;
  1436.  
  1437.   /* If P or B type frame... */
  1438.  
  1439.   if ((vid_stream->picture.code_type == 2) || (vid_stream->picture.code_type == 3)) {
  1440.  
  1441.     /* Parse off forward vector full pixel flag. */
  1442.     get_bits1(&data);
  1443.     if (data) vid_stream->picture.full_pel_forw_vector = TRUE;
  1444.     else vid_stream->picture.full_pel_forw_vector = FALSE;
  1445.  
  1446.     /* Parse of forw_r_code. */
  1447.     get_bits3(&data);
  1448.  
  1449.     /* Decode forw_r_code into forw_r_size and forw_f. */
  1450.  
  1451.     vid_stream->picture.forw_r_size = data - 1;
  1452.     vid_stream->picture.forw_f = (1 << vid_stream->picture.forw_r_size);
  1453.   }
  1454.  
  1455.   /* If B type frame... */
  1456.  
  1457.   if (vid_stream->picture.code_type == 3) {
  1458.  
  1459.     /* Parse off back vector full pixel flag. */
  1460.     get_bits1(&data);
  1461.     if (data) vid_stream->picture.full_pel_back_vector = TRUE;
  1462.     else vid_stream->picture.full_pel_back_vector = FALSE;
  1463.  
  1464.     /* Parse off back_r_code. */
  1465.     get_bits3(&data);
  1466.  
  1467.     /* Decode back_r_code into back_r_size and back_f. */
  1468.  
  1469.     vid_stream->picture.back_r_size = data -1;
  1470.     vid_stream->picture.back_f = (1 << vid_stream->picture.back_r_size);
  1471.   }
  1472.  
  1473.   /* Get extra bit picture info. */
  1474.  
  1475.   if (vid_stream->picture.extra_info != NULL) {
  1476.     free(vid_stream->picture.extra_info);
  1477.     vid_stream->picture.extra_info = NULL;
  1478.   }
  1479.  
  1480.   vid_stream->picture.extra_info = get_extra_bit_info();
  1481.  
  1482.   /* Goto next start code. */
  1483.   next_start_code();
  1484.  
  1485.   /* If start code is extension start code, parse off extension data. */
  1486.  
  1487.   if (next_bits(32, EXT_START_CODE)) {
  1488.     flush_bits(32);
  1489.  
  1490.     if (vid_stream->picture.ext_data != NULL) {
  1491.       free(vid_stream->picture.ext_data);
  1492.       vid_stream->picture.ext_data = NULL;
  1493.     }
  1494.  
  1495.     vid_stream->picture.ext_data = get_ext_data();
  1496.   }
  1497.  
  1498.   /* If start code is user start code, parse off user data. */
  1499.  
  1500.   if (next_bits(32, USER_START_CODE)) {
  1501.     flush_bits(32);
  1502.     
  1503.     if (vid_stream->picture.user_data != NULL) {
  1504.       free(vid_stream->picture.user_data);
  1505.       vid_stream->picture.user_data = NULL;
  1506.     }
  1507.  
  1508.     vid_stream->picture.user_data = get_ext_data();
  1509.   }
  1510.  
  1511.   /* Find a pict image structure in ring buffer not currently locked. */
  1512.  
  1513.   i = 0;
  1514.  
  1515.   while(vid_stream->ring[i]->locked != 0) {
  1516.     if (++i >= RING_BUF_SIZE) {
  1517.       perror("Fatal error. Ring buffer full.");
  1518.       exit(1);
  1519.     }
  1520.   }
  1521.  
  1522.   /* Set current pict image structure to the one just found in ring. */
  1523.  
  1524.   vid_stream->current = vid_stream->ring[i];
  1525.  
  1526.   /* Set time stamp. */
  1527.  
  1528.   vid_stream->current->show_time = time_stamp;
  1529.  
  1530.   /* Reset past macroblock address field. */
  1531.  
  1532.   vid_stream->mblock.past_mb_addr = -1;
  1533.  
  1534.   return PARSE_OK;
  1535. }
  1536.  
  1537.  
  1538. /*
  1539.  *--------------------------------------------------------------
  1540.  *
  1541.  * ParseSlice --
  1542.  *
  1543.  *      Parses off slice header.
  1544.  *
  1545.  * Results:
  1546.  *      Values found in slice header put into video stream structure.
  1547.  *
  1548.  * Side effects:
  1549.  *      Bit stream irreversibly parsed. 
  1550.  *
  1551.  *--------------------------------------------------------------
  1552.  */
  1553.  
  1554. static int
  1555. ParseSlice(vid_stream)
  1556. VidStream *vid_stream;
  1557. {
  1558.   unsigned  int data;
  1559.  
  1560.   /* Flush slice start code. */
  1561.  
  1562.   flush_bits(24);
  1563.  
  1564.   /* Parse off slice vertical position. */
  1565.  
  1566.   get_bits8(&data);
  1567.   vid_stream->slice.vert_pos = data;
  1568.  
  1569.   /* Parse off quantization scale. */
  1570.  
  1571.   get_bits5(&data);
  1572.   vid_stream->slice.quant_scale = data;
  1573.  
  1574.   /* Parse off extra bit slice info. */
  1575.  
  1576.   if (vid_stream->slice.extra_info != NULL) {
  1577.     free(vid_stream->slice.extra_info);
  1578.     vid_stream->slice.extra_info = NULL;
  1579.   }
  1580.   vid_stream->slice.extra_info = get_extra_bit_info();
  1581.  
  1582.   /* Reset past intrablock address. */
  1583.  
  1584.   vid_stream->mblock.past_intra_addr = -2;
  1585.  
  1586.   /* Reset previous recon motion vectors. */
  1587.  
  1588.   vid_stream->mblock.recon_right_for_prev = 0;  
  1589.   vid_stream->mblock.recon_down_for_prev = 0;  
  1590.   vid_stream->mblock.recon_right_back_prev = 0;  
  1591.   vid_stream->mblock.recon_down_back_prev = 0;
  1592.  
  1593.   /* Reset macroblock address. */
  1594.  
  1595.   vid_stream->mblock.mb_address = ((vid_stream->slice.vert_pos-1) *
  1596.                                    vid_stream->mb_width) - 1;
  1597.  
  1598.   /* Reset past dct dc y, cr, and cb values. */
  1599.  
  1600.   vid_stream->block.dct_dc_y_past = 1024;
  1601.   vid_stream->block.dct_dc_cr_past = 1024;
  1602.   vid_stream->block.dct_dc_cb_past = 1024;
  1603.  
  1604.   return PARSE_OK;
  1605. }
  1606.  
  1607.  
  1608. /*
  1609.  *--------------------------------------------------------------
  1610.  *
  1611.  * ParseMacroBlock --
  1612.  *
  1613.  *      Parseoff macroblock. Reconstructs DCT values. Applies
  1614.  *      inverse DCT, reconstructs motion vectors, calculates and
  1615.  *      set pixel values for macroblock in current pict image 
  1616.  *      structure.
  1617.  *
  1618.  * Results:
  1619.  *      Here's where everything really happens. Welcome to the
  1620.  *      heart of darkness.
  1621.  *
  1622.  * Side effects:
  1623.  *      Bit stream irreversibly parsed off.
  1624.  *
  1625.  *--------------------------------------------------------------
  1626.  */
  1627.  
  1628. static int
  1629. ParseMacroBlock(vid_stream)
  1630.      VidStream *vid_stream;
  1631. {
  1632.   int addr_incr;
  1633.   unsigned  int data;
  1634.   int i, recon_right_for, recon_down_for, recon_right_back, recon_down_back;
  1635.   int zero_block_flag;
  1636.   BOOLEAN mb_quant, mb_motion_forw, mb_motion_back, mb_pattern;
  1637.   int sparseFlag;
  1638.  
  1639.   /* Parse off macroblock address increment and add to macroblock
  1640.      address.
  1641.   */
  1642.  
  1643. #ifdef ANALYSIS
  1644.   mbSizeCount = bitCountRead();
  1645. #endif
  1646.  
  1647.   do {
  1648.     DecodeMBAddrInc(&addr_incr);
  1649.     if (addr_incr == MB_ESCAPE) {
  1650.       vid_stream->mblock.mb_address += 33;
  1651.       addr_incr = MB_STUFFING;
  1652.     }
  1653.   } while (addr_incr == MB_STUFFING);
  1654.   vid_stream->mblock.mb_address += addr_incr;
  1655.  
  1656.   if (vid_stream->mblock.mb_address > (vid_stream->mb_height * 
  1657.                                        vid_stream->mb_width - 1))
  1658.     return SKIP_TO_START_CODE;
  1659.  
  1660.   /* If macroblocks have been skipped, process skipped macroblocks. */
  1661.  
  1662.   if (vid_stream->mblock.mb_address-vid_stream->mblock.past_mb_addr > 1) {
  1663.     if (vid_stream->picture.code_type == P_TYPE)
  1664.       ProcessSkippedPFrameMBlocks(vid_stream);
  1665.     else if (vid_stream->picture.code_type == B_TYPE)
  1666.       ProcessSkippedBFrameMBlocks(vid_stream);
  1667.   }
  1668.  
  1669.   /* Set past macroblock address to current macroblock address. */
  1670.  
  1671.   vid_stream->mblock.past_mb_addr = vid_stream->mblock.mb_address;
  1672.  
  1673.   /* Based on picture type decode macroblock type. */
  1674.  
  1675.   switch (vid_stream->picture.code_type) {
  1676.   case I_TYPE:
  1677.     DecodeMBTypeI(&mb_quant, &mb_motion_forw, &mb_motion_back, &mb_pattern,
  1678.                   &(vid_stream->mblock.mb_intra));
  1679.     break;
  1680.  
  1681.   case P_TYPE:
  1682.     DecodeMBTypeP(&mb_quant, &mb_motion_forw, &mb_motion_back, &mb_pattern,
  1683.                   &(vid_stream->mblock.mb_intra));
  1684.     break;
  1685.  
  1686.   case B_TYPE:
  1687.     DecodeMBTypeB(&mb_quant, &mb_motion_forw, &mb_motion_back, &mb_pattern,
  1688.                   &(vid_stream->mblock.mb_intra));
  1689.     break;
  1690.   }
  1691.  
  1692.   /* If quantization flag set, parse off new quantization scale. */
  1693.  
  1694.   if (mb_quant == TRUE) {
  1695.     get_bits5(&data);
  1696.     vid_stream->slice.quant_scale = data;
  1697.   }
  1698.  
  1699.   /* If forward motion vectors exist... */
  1700.  
  1701.   if (mb_motion_forw == TRUE) {
  1702.  
  1703.     /* Parse off and decode horizontal forward motion vector. */
  1704.     DecodeMotionVectors(&vid_stream->mblock.motion_h_forw_code);
  1705.  
  1706.     /* If horiz. forward r data exists, parse off. */
  1707.  
  1708.     if ((vid_stream->picture.forw_f != 1) && 
  1709.         (vid_stream->mblock.motion_h_forw_code != 0)) {
  1710.       get_bitsn(vid_stream->picture.forw_r_size, &data);
  1711.       vid_stream->mblock.motion_h_forw_r = data;
  1712.     }
  1713.  
  1714.     /* Parse off and decode vertical forward motion vector. */
  1715.     DecodeMotionVectors(&vid_stream->mblock.motion_v_forw_code);
  1716.  
  1717.     /* If vert. forw. r data exists, parse off. */
  1718.  
  1719.     if ((vid_stream->picture.forw_f != 1) && 
  1720.         (vid_stream->mblock.motion_v_forw_code != 0)) {
  1721.       get_bitsn(vid_stream->picture.forw_r_size, &data);
  1722.       vid_stream->mblock.motion_v_forw_r = data;
  1723.     }
  1724.   }
  1725.  
  1726.   /* If back motion vectors exist... */
  1727.  
  1728.   if (mb_motion_back == TRUE) {
  1729.  
  1730.     /* Parse off and decode horiz. back motion vector. */
  1731.     DecodeMotionVectors(&vid_stream->mblock.motion_h_back_code);
  1732.     
  1733.     /* If horiz. back r data exists, parse off. */
  1734.  
  1735.     if ((vid_stream->picture.back_f != 1) && 
  1736.         (vid_stream->mblock.motion_h_back_code != 0)) {
  1737.       get_bitsn(vid_stream->picture.back_r_size, &data);
  1738.       vid_stream->mblock.motion_h_back_r = data;
  1739.     }
  1740.  
  1741.     /* Parse off and decode vert. back motion vector. */
  1742.     DecodeMotionVectors(&vid_stream->mblock.motion_v_back_code);
  1743.  
  1744.     /* If vert. back r data exists, parse off. */
  1745.  
  1746.     if ((vid_stream->picture.back_f != 1) && 
  1747.         (vid_stream->mblock.motion_v_back_code != 0)) {
  1748.       get_bitsn(vid_stream->picture.back_r_size, &data);
  1749.       vid_stream->mblock.motion_v_back_r = data;
  1750.     }
  1751.   }
  1752.  
  1753. #ifdef ANALYSIS
  1754.   if (vid_stream->mblock.mb_intra) {
  1755.     stat_a[0].i_mbnum++;
  1756.     mbCBPPtr = stat_a[0].i_mbcbp;
  1757.     mbCoeffPtr = stat_a[0].i_mbcoeff;
  1758.     mbSizePtr = &(stat_a[0].i_mbsize);
  1759.   }
  1760.   else if (mb_motion_back && mb_motion_forw) {
  1761.     stat_a[0].bi_mbnum++;
  1762.     mbCBPPtr = stat_a[0].bi_mbcbp;
  1763.     mbCoeffPtr = stat_a[0].bi_mbcoeff;
  1764.     mbSizePtr = &(stat_a[0].bi_mbsize);
  1765.   }
  1766.   else if (mb_motion_back) {
  1767.     stat_a[0].b_mbnum++;
  1768.     mbCBPPtr = stat_a[0].b_mbcbp;
  1769.     mbCoeffPtr = stat_a[0].b_mbcoeff;
  1770.     mbSizePtr = &(stat_a[0].b_mbsize);
  1771.   } else {
  1772.     stat_a[0].p_mbnum++;
  1773.     mbCBPPtr = stat_a[0].p_mbcbp;
  1774.     mbCoeffPtr = stat_a[0].p_mbcoeff;
  1775.     mbSizePtr = &(stat_a[0].p_mbsize);
  1776.   }
  1777. #endif
  1778.  
  1779.   /* If mblock pattern flag set, parse and decode CBP (code block pattern). */
  1780.  
  1781.   if (mb_pattern == TRUE) {
  1782.     DecodeCBP(&vid_stream->mblock.cbp);
  1783.   } 
  1784.  
  1785.   /* Otherwise, set CBP to zero. */
  1786.  
  1787.   else vid_stream->mblock.cbp = 0;
  1788.  
  1789.  
  1790. #ifdef ANALYSIS
  1791.   mbCBPPtr[vid_stream->mblock.cbp]++;
  1792. #endif
  1793.  
  1794.   /* Reconstruct motion vectors depending on picture type. */
  1795.  
  1796.   if (vid_stream->picture.code_type == P_TYPE) {
  1797.  
  1798.     /* If no forw motion vectors, reset previous and current vectors to 0. */
  1799.  
  1800.     if (!mb_motion_forw) {
  1801.       recon_right_for = 0;
  1802.       recon_down_for = 0;
  1803.       vid_stream->mblock.recon_right_for_prev = 0;
  1804.       vid_stream->mblock.recon_down_for_prev = 0;
  1805.     }
  1806.  
  1807.     /* Otherwise, compute new forw motion vectors. Reset previous vectors
  1808.        to current vectors.
  1809.     */
  1810.  
  1811.     else {
  1812.       ComputeForwVector(&recon_right_for, &recon_down_for);
  1813.     }
  1814.   }
  1815.  
  1816.   if (vid_stream->picture.code_type == B_TYPE) {
  1817.  
  1818.     /* Reset prev. and current vectors to zero if mblock is intracoded. */
  1819.  
  1820.     if (vid_stream->mblock.mb_intra) {
  1821.       vid_stream->mblock.recon_right_for_prev = 0;
  1822.       vid_stream->mblock.recon_down_for_prev = 0;
  1823.       vid_stream->mblock.recon_right_back_prev = 0;
  1824.       vid_stream->mblock.recon_down_back_prev = 0;
  1825.     }
  1826.     else {
  1827.  
  1828.       /* If no forw vectors, current vectors equal prev. vectors. */
  1829.       
  1830.       if (!mb_motion_forw) {
  1831.         recon_right_for = vid_stream->mblock.recon_right_for_prev;
  1832.         recon_down_for = vid_stream->mblock.recon_down_for_prev;
  1833.       }
  1834.       
  1835.       /* Otherwise compute forw. vectors. Reset prev vectors to new values. */
  1836.  
  1837.       else {    
  1838.         ComputeForwVector(&recon_right_for, &recon_down_for);
  1839.       }
  1840.  
  1841.       /* If no back vectors, set back vectors to prev back vectors. */
  1842.  
  1843.       if (!mb_motion_back) {
  1844.         recon_right_back = vid_stream->mblock.recon_right_back_prev;
  1845.         recon_down_back = vid_stream->mblock.recon_down_back_prev;
  1846.       }
  1847.  
  1848.       /* Otherwise compute new vectors and reset prev. back vectors. */
  1849.  
  1850.       else {
  1851.         ComputeBackVector(&recon_right_back, &recon_down_back);
  1852.       }
  1853.  
  1854.       /* Store vector existance flags in structure for possible 
  1855.          skipped macroblocks to follow.
  1856.       */
  1857.  
  1858.       vid_stream->mblock.bpict_past_forw = mb_motion_forw;
  1859.       vid_stream->mblock.bpict_past_back = mb_motion_back;
  1860.     }
  1861.   }
  1862.  
  1863.   /* For each possible block in macroblock. */
  1864.  
  1865.   for (i=0; i<6; i++) {
  1866.  
  1867.     /* If block exists... */
  1868.  
  1869.     if ((vid_stream->mblock.mb_intra) || 
  1870.         (vid_stream->mblock.cbp & (1<<(5-i)))) {
  1871.  
  1872.       /* Unset Zero Block Flag. */
  1873.  
  1874.       zero_block_flag = 0;
  1875.  
  1876.       if (ditherType == GRAY_DITHER || ditherType == MONO_DITHER || ditherType == MONO_THRESHOLD) {
  1877.  
  1878.     if (i < 5) {
  1879.       /* Reconstruct DCT coeffs in block. */
  1880.       
  1881.       sparseFlag = ParseReconBlock(i);
  1882.       
  1883.       /* Run through inverse DCT. */
  1884.  
  1885.     }
  1886.     else {
  1887.       /* Parse and throw away block. */
  1888.  
  1889.       ParseAwayBlock(i);
  1890.     }
  1891.       }
  1892.     
  1893.       else {
  1894.     
  1895.     /* Parse and reconstruct block. */
  1896.     
  1897.     sparseFlag = ParseReconBlock(i);
  1898.     
  1899.       }
  1900.     }
  1901.  
  1902.     /* Otherwise, set zero block flag. */
  1903.  
  1904.     else {
  1905.       zero_block_flag = 1;
  1906.     }
  1907.  
  1908.     if (ditherType == GRAY_DITHER || ditherType == MONO_DITHER || ditherType == MONO_THRESHOLD) {
  1909.       if (i < 5) {
  1910.     
  1911.     /* If macroblock is intra coded... */
  1912.     if (vid_stream->mblock.mb_intra) {
  1913.       ReconIMBlock(vid_stream, i);
  1914.     }
  1915.     else if (mb_motion_forw && mb_motion_back) {
  1916.       ReconBiMBlock(vid_stream, i, recon_right_for, recon_down_for, recon_right_back,
  1917.             recon_down_back, zero_block_flag);
  1918.     }
  1919.     else if (mb_motion_forw || (vid_stream->picture.code_type == P_TYPE)) {
  1920.       ReconPMBlock(vid_stream, i, recon_right_for, recon_down_for, zero_block_flag);
  1921.     }
  1922.     else if (mb_motion_back) {
  1923.       ReconBMBlock(vid_stream, i, recon_right_back, recon_down_back, zero_block_flag);
  1924.     }      
  1925.       }
  1926.     } 
  1927.     
  1928.     else {
  1929.       /* If macroblock is intra coded... */
  1930.       if (vid_stream->mblock.mb_intra) {
  1931.     ReconIMBlock(vid_stream, i);
  1932.       }
  1933.       else if (mb_motion_forw && mb_motion_back) {
  1934.     ReconBiMBlock(vid_stream, i, recon_right_for, recon_down_for, recon_right_back,
  1935.               recon_down_back, zero_block_flag);
  1936.       }
  1937.       else if (mb_motion_forw || (vid_stream->picture.code_type == P_TYPE)) {
  1938.     ReconPMBlock(vid_stream, i, recon_right_for, recon_down_for, zero_block_flag);
  1939.       }
  1940.       else if (mb_motion_back) {
  1941.     ReconBMBlock(vid_stream, i, recon_right_back, recon_down_back, zero_block_flag);
  1942.       }
  1943.     }
  1944.   }
  1945.   
  1946.   /* If D Type picture, flush marker bit. */
  1947.   
  1948.   if (vid_stream->picture.code_type == 4) flush_bits(1);
  1949.   
  1950.   /* If macroblock was intracoded, set macroblock past intra address. */
  1951.   
  1952.   if (vid_stream->mblock.mb_intra) vid_stream->mblock.past_intra_addr =
  1953.     vid_stream->mblock.mb_address;
  1954.  
  1955. #ifdef ANALYSIS
  1956.   *mbSizePtr += bitCountRead() - mbSizeCount;
  1957. #endif
  1958.   return PARSE_OK;
  1959.  
  1960. }
  1961.  
  1962.  
  1963. /*
  1964.  *--------------------------------------------------------------
  1965.  *
  1966.  * ReconIMBlock --
  1967.  *
  1968.  *    Reconstructs intra coded macroblock.
  1969.  *
  1970.  * Results:
  1971.  *    None.
  1972.  *
  1973.  * Side effects:
  1974.  *    None.
  1975.  *
  1976.  *--------------------------------------------------------------
  1977.  */
  1978.  
  1979. static void 
  1980. ReconIMBlock(vid_stream, bnum)
  1981.      VidStream *vid_stream;
  1982.      int bnum;
  1983. {
  1984.   int mb_row, mb_col, row, col, row_size, rr, cc;
  1985.   unsigned char *dest;
  1986.  
  1987.   /* Calculate macroblock row and column from address. */
  1988.  
  1989.   mb_row = vid_stream->mblock.mb_address / vid_stream->mb_width;
  1990.   mb_col = vid_stream->mblock.mb_address % vid_stream->mb_width;
  1991.   
  1992.  
  1993.   /* If block is luminance block... */
  1994.  
  1995.   if (bnum<4) {
  1996.     
  1997.     /* Calculate row and col values for upper left pixel of block. */
  1998.  
  1999.     row = mb_row * 16; col = mb_col * 16;
  2000.     if (bnum>1) row += 8;
  2001.     if (bnum%2) col += 8;
  2002.  
  2003.     /* Set dest to luminance plane of current pict image. */
  2004.  
  2005.     dest = vid_stream->current->luminance;
  2006.  
  2007.     /* Establish row size. */
  2008.  
  2009.     row_size = vid_stream->mb_width*16;
  2010.   }
  2011.  
  2012.   /* Otherwise if block is Cr block... */
  2013.  
  2014.   else if (bnum==4) {
  2015.  
  2016.     /* Set dest to Cr plane of current pict image. */
  2017.  
  2018.     dest = vid_stream->current->Cr;
  2019.  
  2020.     /* Establish row size. */
  2021.  
  2022.     row_size = vid_stream->mb_width*8;
  2023.  
  2024.     /* Calculate row,col for upper left pixel of block. */
  2025.  
  2026.     row = mb_row*8;
  2027.     col = mb_col*8;
  2028.   }
  2029.  
  2030.   /* Otherwise block is Cb block, and ... */
  2031.  
  2032.   else {
  2033.  
  2034.     /* Set dest to Cb plane of current pict image. */
  2035.  
  2036.     dest = vid_stream->current->Cb;
  2037.  
  2038.     /* Establish row size. */
  2039.  
  2040.     row_size = vid_stream->mb_width*8;
  2041.  
  2042.     /* Calculate row,col for upper left pixel value of block. */
  2043.  
  2044.     row = mb_row*8; col = mb_col*8;
  2045.   }
  2046.  
  2047.   /* For each pixel in block, set to cropped reconstructed value
  2048.      from inverse dct. 
  2049.   */
  2050.   {
  2051.       short *sp = &vid_stream->block.dct_recon[0][0];
  2052.       unsigned char *cm = cropTbl + MAX_NEG_CROP;
  2053.       dest += row * row_size + col;
  2054.       for(rr = 0; rr < 8; rr++, sp += 8, dest += row_size) {
  2055.       dest[0] = cm[sp[0]];    assertCrop(sp[0]);
  2056.       dest[1] = cm[sp[1]];    assertCrop(sp[1]);
  2057.       dest[2] = cm[sp[2]];    assertCrop(sp[2]);
  2058.       dest[3] = cm[sp[3]];    assertCrop(sp[3]);
  2059.       dest[4] = cm[sp[4]];    assertCrop(sp[4]);
  2060.       dest[5] = cm[sp[5]];    assertCrop(sp[5]);
  2061.       dest[6] = cm[sp[6]];    assertCrop(sp[6]);
  2062.       dest[7] = cm[sp[7]];    assertCrop(sp[7]);
  2063.       }
  2064.   }
  2065. }
  2066.  
  2067.  
  2068. /*
  2069.  *--------------------------------------------------------------
  2070.  *
  2071.  * ReconPMBlock --
  2072.  *
  2073.  *    Reconstructs forward predicted macroblocks.
  2074.  *
  2075.  * Results:
  2076.  *      None.
  2077.  *
  2078.  * Side effects:
  2079.  *      None.
  2080.  *
  2081.  *--------------------------------------------------------------
  2082.  */
  2083.  
  2084. static void 
  2085. ReconPMBlock(vid_stream, bnum, recon_right_for, recon_down_for, zflag)
  2086. VidStream * vid_stream;
  2087. int bnum, recon_right_for, recon_down_for, zflag;
  2088. {
  2089.   int mb_row, mb_col, row, col, row_size, rr, cc;
  2090.   unsigned char *dest, *past;
  2091.   int right_for, down_for, right_half_for, down_half_for;
  2092.   unsigned char *rindex1, *rindex2;
  2093.   unsigned char *index;
  2094.   int val;
  2095.   short int *blockvals;
  2096.  
  2097.   /* Calculate macroblock row and column from address. */
  2098.  
  2099.   mb_row = vid_stream->mblock.mb_address / vid_stream->mb_width;
  2100.   mb_col = vid_stream->mblock.mb_address % vid_stream->mb_width;
  2101.  
  2102.   if (bnum<4) {
  2103.  
  2104.     /* Calculate right_for, down_for motion vectors. */
  2105.  
  2106.     right_for = recon_right_for >> 1;
  2107.     down_for = recon_down_for >> 1;
  2108.     right_half_for = recon_right_for & 0x1;
  2109.     down_half_for = recon_down_for & 0x1;
  2110.  
  2111.     /* Set dest to luminance plane of current pict image. */
  2112.  
  2113.     dest = vid_stream->current->luminance;
  2114.  
  2115.     if (vid_stream->picture.code_type == B_TYPE) {
  2116.       if (vid_stream->past != NULL) 
  2117.         past = vid_stream->past->luminance;
  2118.     }
  2119.     else {
  2120.  
  2121.       /* Set predicitive frame to current future frame. */
  2122.  
  2123.       if (vid_stream->future != NULL) 
  2124.         past = vid_stream->future->luminance;
  2125.     }
  2126.  
  2127.     /* Establish row size. */
  2128.  
  2129.     row_size = vid_stream->mb_width << 4;
  2130.  
  2131.     /* Calculate row,col of upper left pixel in block. */
  2132.  
  2133.     row = mb_row << 4; col = mb_col << 4;
  2134.     if (bnum>1) row += 8;
  2135.     if (bnum%2) col += 8;
  2136.   } 
  2137.  
  2138.   /* Otherwise, block is NOT luminance block, ... */
  2139.  
  2140.   else {
  2141.  
  2142.     /* Construct motion vectors. */
  2143.  
  2144.     right_for = recon_right_for >> 2;
  2145.     down_for = recon_down_for >> 2;
  2146.     right_half_for = recon_right_for & 0x2;
  2147.     down_half_for = recon_down_for & 0x2;
  2148.  
  2149.     /* Establish row size. */
  2150.  
  2151.     row_size = vid_stream->mb_width << 3;
  2152.  
  2153.     /* Calculate row,col of upper left pixel in block. */
  2154.  
  2155.     row = mb_row << 3; col = mb_col << 3;
  2156.  
  2157.     /* If block is Cr block... */
  2158.  
  2159.     if (bnum== 4) {
  2160.  
  2161.       /* Set dest to Cr plane of current pict image. */
  2162.  
  2163.       dest = vid_stream->current->Cr;
  2164.  
  2165.       if (vid_stream->picture.code_type == B_TYPE) {
  2166.         
  2167.         if (vid_stream->past != NULL)
  2168.           past = vid_stream->past->Cr;
  2169.       }
  2170.       else {
  2171.         if (vid_stream->future != NULL)
  2172.           past = vid_stream->future->Cr;
  2173.       }
  2174.     }
  2175.  
  2176.     /* Otherwise, block is Cb block... */
  2177.     
  2178.     else {
  2179.  
  2180.       /* Set dest to Cb plane of current pict image. */
  2181.  
  2182.       dest = vid_stream->current->Cb;
  2183.  
  2184.       if (vid_stream->picture.code_type == B_TYPE) {
  2185.         if (vid_stream->past != NULL)
  2186.           past = vid_stream->past->Cb;
  2187.       }
  2188.       else {
  2189.         if (vid_stream->future != NULL) 
  2190.           past = vid_stream->future->Cb;
  2191.       }
  2192.     }
  2193.   }
  2194.  
  2195.   /* For each pixel in block... */
  2196.  
  2197.   index = dest+(row*row_size)+col;
  2198.   rindex1 = past+(row+down_for)*row_size+col+right_for;
  2199.  
  2200.   blockvals = &(vid_stream->block.dct_recon[0][0]);
  2201.  
  2202.   /*
  2203.    * Calculate predictive pixel value based on motion vectors
  2204.    * and copy to dest plane.
  2205.    */
  2206.  
  2207.   if ((!down_half_for) && (!right_half_for)) {
  2208.     unsigned char *cm = cropTbl + MAX_NEG_CROP;
  2209.     if (!zflag)
  2210.       for (rr = 0; rr < 8; rr++) {
  2211.     index[0] = cm[(int)rindex1[0] + (int)blockvals[0]];
  2212.     index[1] = cm[(int)rindex1[1] + (int)blockvals[1]];
  2213.     index[2] = cm[(int)rindex1[2] + (int)blockvals[2]];
  2214.     index[3] = cm[(int)rindex1[3] + (int)blockvals[3]];
  2215.     index[4] = cm[(int)rindex1[4] + (int)blockvals[4]];
  2216.     index[5] = cm[(int)rindex1[5] + (int)blockvals[5]];
  2217.     index[6] = cm[(int)rindex1[6] + (int)blockvals[6]];
  2218.     index[7] = cm[(int)rindex1[7] + (int)blockvals[7]];
  2219.     blockvals += 8;
  2220.     index += row_size;
  2221.     rindex1 += row_size;
  2222.       }   
  2223.     else
  2224.       for (rr = 0; rr < 8; rr++) {
  2225.     index[0] = rindex1[0];
  2226.     index[1] = rindex1[1];
  2227.     index[2] = rindex1[2];
  2228.     index[3] = rindex1[3];
  2229.     index[4] = rindex1[4];
  2230.     index[5] = rindex1[5];
  2231.     index[6] = rindex1[6];
  2232.     index[7] = rindex1[7];
  2233.     index += row_size;
  2234.     rindex1 += row_size;
  2235.       }   
  2236.   }
  2237.   else {
  2238.     unsigned char *cm = cropTbl + MAX_NEG_CROP;
  2239.     rindex2 = rindex1 + right_half_for + (down_half_for * row_size);
  2240.     if (!zflag)
  2241.       for (rr = 0; rr < 8; rr++) {
  2242.         index[0] = cm[((int)(rindex1[0] + rindex2[0])>>1) + blockvals[0]];
  2243.         index[1] = cm[((int)(rindex1[1] + rindex2[1])>>1) + blockvals[1]];
  2244.         index[2] = cm[((int)(rindex1[2] + rindex2[2])>>1) + blockvals[2]];
  2245.         index[3] = cm[((int)(rindex1[3] + rindex2[3])>>1) + blockvals[3]];
  2246.         index[4] = cm[((int)(rindex1[4] + rindex2[4])>>1) + blockvals[4]];
  2247.         index[5] = cm[((int)(rindex1[5] + rindex2[5])>>1) + blockvals[5]];
  2248.         index[6] = cm[((int)(rindex1[6] + rindex2[6])>>1) + blockvals[6]];
  2249.         index[7] = cm[((int)(rindex1[7] + rindex2[7])>>1) + blockvals[7]];
  2250.     blockvals += 8;
  2251.     index += row_size;
  2252.     rindex1 += row_size;
  2253.     rindex2 += row_size;
  2254.       }   
  2255.     else 
  2256.       for (rr = 0; rr < 8; rr++) {
  2257.         index[0] = (int)(rindex1[0] + rindex2[0]) >> 1;
  2258.         index[1] = (int)(rindex1[1] + rindex2[1]) >> 1;
  2259.         index[2] = (int)(rindex1[2] + rindex2[2]) >> 1;
  2260.         index[3] = (int)(rindex1[3] + rindex2[3]) >> 1;
  2261.         index[4] = (int)(rindex1[4] + rindex2[4]) >> 1;
  2262.         index[5] = (int)(rindex1[5] + rindex2[5]) >> 1;
  2263.         index[6] = (int)(rindex1[6] + rindex2[6]) >> 1;
  2264.         index[7] = (int)(rindex1[7] + rindex2[7]) >> 1;
  2265.     index += row_size;
  2266.     rindex1 += row_size;
  2267.     rindex2 += row_size;
  2268.       }   
  2269.   }
  2270. }
  2271.  
  2272. /*
  2273.  *--------------------------------------------------------------
  2274.  *
  2275.  * ReconBMBlock --
  2276.  *
  2277.  *    Reconstructs back predicted macroblocks.
  2278.  *
  2279.  * Results:
  2280.  *      None.
  2281.  *
  2282.  * Side effects:
  2283.  *      None.
  2284.  *
  2285.  *--------------------------------------------------------------
  2286.  */
  2287.  
  2288. static void 
  2289. ReconBMBlock(vid_stream, bnum, recon_right_back, recon_down_back, zflag)
  2290.      VidStream *vid_stream;
  2291.      int bnum, recon_right_back, recon_down_back, zflag;
  2292. {
  2293.   int mb_row, mb_col, row, col, row_size, rr, cc;
  2294.   unsigned char *dest, *future;
  2295.   int right_back, down_back, right_half_back, down_half_back;
  2296.   unsigned char  *rindex1, *rindex2;
  2297.   unsigned char  *index;
  2298.   int val;
  2299.   short int *blockvals;
  2300.  
  2301.   /* Calculate macroblock row and column from address. */
  2302.  
  2303.   mb_row = vid_stream->mblock.mb_address / vid_stream->mb_width;
  2304.   mb_col = vid_stream->mblock.mb_address % vid_stream->mb_width;
  2305.  
  2306.   /* If block is luminance block... */
  2307.  
  2308.   if (bnum<4) {
  2309.  
  2310.     /* Calculate right_back, down_bakc motion vectors. */
  2311.  
  2312.     right_back = recon_right_back >> 1;
  2313.     down_back = recon_down_back >> 1;
  2314.     right_half_back = recon_right_back & 0x1;
  2315.     down_half_back = recon_down_back & 0x1;
  2316.  
  2317.     /* Set dest to luminance plane of current pict image. */
  2318.  
  2319.     dest = vid_stream->current->luminance;
  2320.  
  2321.     /* If future frame exists, set future to luminance plane
  2322.        of future frame.
  2323.        */
  2324.  
  2325.     if (vid_stream->future != NULL) 
  2326.       future = vid_stream->future->luminance;
  2327.  
  2328.     /* Establish row size. */
  2329.  
  2330.     row_size = vid_stream->mb_width << 4;
  2331.  
  2332.     /* Calculate row,col of upper left pixel in block. */
  2333.  
  2334.     row = mb_row << 4; col = mb_col << 4;
  2335.     if (bnum>1) row += 8;
  2336.     if (bnum%2) col += 8;
  2337.   } 
  2338.  
  2339.   /* Otherwise, block is NOT luminance block, ... */
  2340.  
  2341.   else {
  2342.  
  2343.     /* Construct motion vectors. */
  2344.  
  2345.     right_back = recon_right_back >> 2;
  2346.     down_back = recon_down_back >> 2;
  2347.     right_half_back = recon_right_back & 0x2;
  2348.     down_half_back = recon_down_back & 0x2;
  2349.  
  2350.     /* Establish row size. */
  2351.  
  2352.     row_size = vid_stream->mb_width << 3;
  2353.     
  2354.     /* Calculate row,col of upper left pixel in block. */
  2355.     
  2356.     row = mb_row << 3; col = mb_col << 3;
  2357.     
  2358.     /* If block is Cr block... */
  2359.  
  2360.     if (bnum== 4) {
  2361.  
  2362.       /* Set dest to Cr plane of current pict image. */
  2363.  
  2364.       dest = vid_stream->current->Cr;
  2365.  
  2366.       /* If future frame exists, set future to Cr plane of future image. */
  2367.       
  2368.       if (vid_stream->future != NULL)
  2369.         future = vid_stream->future->Cr;
  2370.     }
  2371.         
  2372.     /* Otherwise, block is Cb block... */
  2373.  
  2374.     else {
  2375.  
  2376.       /* Set dest to Cb plane of current pict image. */
  2377.  
  2378.       dest = vid_stream->current->Cb;
  2379.  
  2380.       /* If future frame exists, set future to Cb plane of future frame. */
  2381.  
  2382.       if (vid_stream->future != NULL)
  2383.         future = vid_stream->future->Cb;
  2384.     }
  2385.   }
  2386.  
  2387.   /* For each pixel in block do... */
  2388.  
  2389.   index = dest + (row*row_size)+col;
  2390.   rindex1 = future + (row+down_back)*row_size+col+right_back;
  2391.  
  2392.   blockvals = &(vid_stream->block.dct_recon[0][0]);
  2393.  
  2394.   if ((!right_half_back)&&(!down_half_back)) {
  2395.     unsigned char *cm = cropTbl + MAX_NEG_CROP;
  2396.     if (!zflag) 
  2397.       for (rr = 0; rr < 8; rr++) {
  2398.     index[0] = cm[(int)rindex1[0] + (int)blockvals[0]];
  2399.     index[1] = cm[(int)rindex1[1] + (int)blockvals[1]];
  2400.     index[2] = cm[(int)rindex1[2] + (int)blockvals[2]];
  2401.     index[3] = cm[(int)rindex1[3] + (int)blockvals[3]];
  2402.     index[4] = cm[(int)rindex1[4] + (int)blockvals[4]];
  2403.     index[5] = cm[(int)rindex1[5] + (int)blockvals[5]];
  2404.     index[6] = cm[(int)rindex1[6] + (int)blockvals[6]];
  2405.     index[7] = cm[(int)rindex1[7] + (int)blockvals[7]];
  2406.     blockvals += 8;
  2407.     index += row_size;
  2408.     rindex1 += row_size;
  2409.       }
  2410.     else
  2411.       for (rr = 0; rr < 8; rr++) {
  2412.     index[0] = rindex1[0];
  2413.     index[1] = rindex1[1];
  2414.     index[2] = rindex1[2];
  2415.     index[3] = rindex1[3];
  2416.     index[4] = rindex1[4];
  2417.     index[5] = rindex1[5];
  2418.     index[6] = rindex1[6];
  2419.     index[7] = rindex1[7];
  2420.     index += row_size;
  2421.     rindex1 += row_size;
  2422.       }
  2423.   }
  2424.   else {
  2425.     unsigned char *cm = cropTbl + MAX_NEG_CROP;
  2426.     rindex2 = rindex1 + right_half_back + (down_half_back*row_size);
  2427.     if (!zflag)
  2428.       for (rr = 0; rr < 8; rr++) {
  2429.         index[0] = cm[((int)(rindex1[0] + rindex2[0])>>1) + blockvals[0]];
  2430.         index[1] = cm[((int)(rindex1[1] + rindex2[1])>>1) + blockvals[1]];
  2431.         index[2] = cm[((int)(rindex1[2] + rindex2[2])>>1) + blockvals[2]];
  2432.         index[3] = cm[((int)(rindex1[3] + rindex2[3])>>1) + blockvals[3]];
  2433.         index[4] = cm[((int)(rindex1[4] + rindex2[4])>>1) + blockvals[4]];
  2434.         index[5] = cm[((int)(rindex1[5] + rindex2[5])>>1) + blockvals[5]];
  2435.         index[6] = cm[((int)(rindex1[6] + rindex2[6])>>1) + blockvals[6]];
  2436.         index[7] = cm[((int)(rindex1[7] + rindex2[7])>>1) + blockvals[7]];
  2437.     blockvals += 8;
  2438.     index += row_size;
  2439.     rindex1 += row_size;
  2440.     rindex2 += row_size;
  2441.       }
  2442.     else 
  2443.       for (rr = 0; rr < 8; rr++) {
  2444.         index[0] = (int)(rindex1[0] + rindex2[0]) >> 1;
  2445.         index[1] = (int)(rindex1[1] + rindex2[1]) >> 1;
  2446.         index[2] = (int)(rindex1[2] + rindex2[2]) >> 1;
  2447.         index[3] = (int)(rindex1[3] + rindex2[3]) >> 1;
  2448.         index[4] = (int)(rindex1[4] + rindex2[4]) >> 1;
  2449.         index[5] = (int)(rindex1[5] + rindex2[5]) >> 1;
  2450.         index[6] = (int)(rindex1[6] + rindex2[6]) >> 1;
  2451.         index[7] = (int)(rindex1[7] + rindex2[7]) >> 1;
  2452.     index += row_size;
  2453.     rindex1 += row_size;
  2454.     rindex2 += row_size;
  2455.       }
  2456.   }
  2457. }
  2458.  
  2459.  
  2460. /*
  2461.  *--------------------------------------------------------------
  2462.  *
  2463.  * ReconBiMBlock --
  2464.  *
  2465.  *    Reconstructs bidirectionally predicted macroblocks.
  2466.  *
  2467.  * Results:
  2468.  *      None.
  2469.  *
  2470.  * Side effects:
  2471.  *      None.
  2472.  *
  2473.  *--------------------------------------------------------------
  2474.  */
  2475.  
  2476. static void 
  2477. ReconBiMBlock(vid_stream, bnum, recon_right_for, recon_down_for, 
  2478.               recon_right_back, recon_down_back, zflag)
  2479.      VidStream *vid_stream;
  2480.      int bnum, recon_right_for, recon_down_for, recon_right_back, recon_down_back;
  2481.      int zflag;
  2482. {
  2483.   int mb_row, mb_col, row, col, row_size, rr, cc;
  2484.   unsigned char *dest, *past, *future;
  2485.   int right_for, down_for, right_half_for, down_half_for;
  2486.   int right_back, down_back, right_half_back, down_half_back;
  2487.   unsigned char *index, *rindex1, *bindex1, *rindex2, *bindex2;
  2488.   short int *blockvals;
  2489.   int val;
  2490.  
  2491.   /* Calculate macroblock row and column from address. */
  2492.  
  2493.   mb_row = vid_stream->mblock.mb_address / vid_stream->mb_width;
  2494.   mb_col = vid_stream->mblock.mb_address % vid_stream->mb_width;
  2495.   
  2496.   /* If block is luminance block... */
  2497.  
  2498.   if (bnum<4) {
  2499.  
  2500.     /* Calculate right_for, down_for, right_half_for, down_half_for,
  2501.        right_back, down_bakc, right_half_back, and down_half_back,
  2502.        motion vectors.
  2503.     */
  2504.  
  2505.     right_for = recon_right_for >> 1;
  2506.     down_for = recon_down_for >> 1;
  2507.     right_half_for = recon_right_for & 0x1;
  2508.     down_half_for = recon_down_for & 0x1;
  2509.  
  2510.     right_back = recon_right_back >> 1;
  2511.     down_back = recon_down_back >> 1;
  2512.     right_half_back = recon_right_back & 0x1;
  2513.     down_half_back = recon_down_back & 0x1;
  2514.  
  2515.     /* Set dest to luminance plane of current pict image. */
  2516.  
  2517.     dest = vid_stream->current->luminance;
  2518.  
  2519.     /* If past frame exists, set past to luminance plane of past frame. */
  2520.  
  2521.     if (vid_stream->past != NULL)
  2522.       past = vid_stream->past->luminance;
  2523.     
  2524.     /* If future frame exists, set future to luminance plane
  2525.        of future frame.
  2526.        */
  2527.  
  2528.     if (vid_stream->future != NULL) 
  2529.       future = vid_stream->future->luminance;
  2530.   
  2531.     /* Establish row size. */
  2532.     
  2533.     row_size = (vid_stream->mb_width << 4);
  2534.   
  2535.     /* Calculate row,col of upper left pixel in block. */
  2536.  
  2537.     row = (mb_row << 4); col = (mb_col << 4);
  2538.     if (bnum>1) row += 8;
  2539.     if (bnum & 0x01) col += 8;
  2540.   } 
  2541.  
  2542.   /* Otherwise, block is NOT luminance block, ... */
  2543.  
  2544.   else {
  2545.  
  2546.     /* Construct motion vectors. */
  2547.  
  2548.     right_for = recon_right_for >> 2;
  2549.     down_for = recon_down_for >> 2;
  2550.     right_half_for = recon_right_for & 0x2;
  2551.     down_half_for = recon_down_for & 0x2;
  2552.  
  2553.     right_back = recon_right_back >> 2;
  2554.     down_back = recon_down_back >> 2;
  2555.     right_half_back = recon_right_back & 0x2;
  2556.     down_half_back = recon_down_back & 0x2;
  2557.     
  2558.     /* Establish row size. */
  2559.  
  2560.     row_size = (vid_stream->mb_width << 3);
  2561.  
  2562.     /* Calculate row,col of upper left pixel in block. */
  2563.  
  2564.     row = (mb_row << 3); col = (mb_col << 3);
  2565.  
  2566.     /* If block is Cr block... */
  2567.  
  2568.     if (bnum== 4) {
  2569.  
  2570.       /* Set dest to Cr plane of current pict image. */
  2571.  
  2572.       dest = vid_stream->current->Cr;
  2573.  
  2574.       /* If past frame exists, set past to Cr plane of past image. */
  2575.  
  2576.       if (vid_stream->past != NULL)
  2577.         past = vid_stream->past->Cr;
  2578.  
  2579.       /* If future frame exists, set future to Cr plane of future image. */
  2580.  
  2581.       if (vid_stream->future != NULL)
  2582.         future = vid_stream->future->Cr;
  2583.     }
  2584.     /* Otherwise, block is Cb block... */
  2585.     
  2586.     else {
  2587.  
  2588.       /* Set dest to Cb plane of current pict image. */
  2589.  
  2590.       dest = vid_stream->current->Cb;
  2591.  
  2592.       /* If past frame exists, set past to Cb plane of past frame. */
  2593.  
  2594.       if (vid_stream->past != NULL)
  2595.         past = vid_stream->past->Cb;
  2596.       
  2597.       /* If future frame exists, set future to Cb plane of future frame. */
  2598.  
  2599.       if (vid_stream->future != NULL)
  2600.         future = vid_stream->future->Cb;
  2601.     }
  2602.   }
  2603.  
  2604.   /* For each pixel in block... */
  2605.  
  2606.   index = dest+(row*row_size)+col;
  2607.   rindex1 = past+(row+down_for)*row_size+col+right_for;
  2608.   bindex1 = future+(row+down_back)*row_size+col+right_back;
  2609.  
  2610.   blockvals =  (short int *) &( vid_stream->block.dct_recon[0][0]);
  2611.  
  2612.   if ((!down_half_for) && (!right_half_for) &&
  2613.       (!down_half_back) && (!right_half_back)) {
  2614.       unsigned char *cm = cropTbl + MAX_NEG_CROP;
  2615.     if (!zflag)
  2616.       for (rr = 0; rr < 8; rr++) {
  2617.         index[0] = cm[((int)(rindex1[0] + bindex1[0])>>1) + blockvals[0]];
  2618.         index[1] = cm[((int)(rindex1[1] + bindex1[1])>>1) + blockvals[1]];
  2619.         index[2] = cm[((int)(rindex1[2] + bindex1[2])>>1) + blockvals[2]];
  2620.         index[3] = cm[((int)(rindex1[3] + bindex1[3])>>1) + blockvals[3]];
  2621.         index[4] = cm[((int)(rindex1[4] + bindex1[4])>>1) + blockvals[4]];
  2622.         index[5] = cm[((int)(rindex1[5] + bindex1[5])>>1) + blockvals[5]];
  2623.         index[6] = cm[((int)(rindex1[6] + bindex1[6])>>1) + blockvals[6]];
  2624.         index[7] = cm[((int)(rindex1[7] + bindex1[7])>>1) + blockvals[7]];
  2625.     blockvals += 8;
  2626.     index += row_size;
  2627.     rindex1 += row_size;
  2628.     bindex1 += row_size;
  2629.       }
  2630.     else
  2631.       for (rr = 0; rr < 8; rr++) {
  2632.         index[0] = (int)(rindex1[0] + bindex1[0]) >> 1;
  2633.         index[1] = (int)(rindex1[1] + bindex1[1]) >> 1;
  2634.         index[2] = (int)(rindex1[2] + bindex1[2]) >> 1;
  2635.         index[3] = (int)(rindex1[3] + bindex1[3]) >> 1;
  2636.         index[4] = (int)(rindex1[4] + bindex1[4]) >> 1;
  2637.         index[5] = (int)(rindex1[5] + bindex1[5]) >> 1;
  2638.         index[6] = (int)(rindex1[6] + bindex1[6]) >> 1;
  2639.         index[7] = (int)(rindex1[7] + bindex1[7]) >> 1;
  2640.     index += row_size;
  2641.     rindex1 += row_size;
  2642.     bindex1 += row_size;
  2643.       }
  2644.   }
  2645.   else {
  2646.  
  2647.     unsigned char *cm = cropTbl + MAX_NEG_CROP;
  2648.     rindex2 = rindex1 + right_half_for + (row_size * down_half_for);
  2649.     bindex2 = bindex1 + right_half_back + (row_size * down_half_back);
  2650.  
  2651.     if (!zflag)
  2652.       for (rr = 0; rr < 8; rr++) {
  2653.     index[0] = cm[((int)(rindex1[0] + bindex1[0] + 
  2654.                  rindex2[0] + bindex2[0]) >> 2) + blockvals[0]];
  2655.     index[1] = cm[((int)(rindex1[1] + bindex1[1] + 
  2656.                  rindex2[1] + bindex2[1]) >> 2) + blockvals[1]];
  2657.     index[2] = cm[((int)(rindex1[2] + bindex1[2] + 
  2658.                  rindex2[2] + bindex2[2]) >> 2) + blockvals[2]];
  2659.     index[3] = cm[((int)(rindex1[3] + bindex1[3] + 
  2660.                  rindex2[3] + bindex2[3]) >> 2) + blockvals[3]];
  2661.     index[4] = cm[((int)(rindex1[4] + bindex1[4] + 
  2662.                  rindex2[4] + bindex2[4]) >> 2) + blockvals[4]];
  2663.     index[5] = cm[((int)(rindex1[5] + bindex1[5] + 
  2664.                  rindex2[5] + bindex2[5]) >> 2) + blockvals[5]];
  2665.     index[6] = cm[((int)(rindex1[6] + bindex1[6] + 
  2666.                  rindex2[6] + bindex2[6]) >> 2) + blockvals[6]];
  2667.     index[7] = cm[((int)(rindex1[7] + bindex1[7] + 
  2668.                  rindex2[7] + bindex2[7]) >> 2) + blockvals[7]];
  2669.     blockvals += 8;
  2670.     index += row_size;
  2671.     rindex1 += row_size;
  2672.     bindex1 += row_size;
  2673.     rindex2 += row_size;
  2674.     bindex2 += row_size;
  2675.       }
  2676.     else 
  2677.       for (rr = 0; rr < 8; rr++) {
  2678.         index[0] = (int)(rindex1[0] + bindex1[0] + rindex2[0] + bindex2[0]) >>2;
  2679.         index[1] = (int)(rindex1[1] + bindex1[1] + rindex2[1] + bindex2[1]) >>2;
  2680.         index[2] = (int)(rindex1[2] + bindex1[2] + rindex2[2] + bindex2[2]) >>2;
  2681.         index[3] = (int)(rindex1[3] + bindex1[3] + rindex2[3] + bindex2[3]) >>2;
  2682.         index[4] = (int)(rindex1[4] + bindex1[4] + rindex2[4] + bindex2[4]) >>2;
  2683.         index[5] = (int)(rindex1[5] + bindex1[5] + rindex2[5] + bindex2[5]) >>2;
  2684.         index[6] = (int)(rindex1[6] + bindex1[6] + rindex2[6] + bindex2[6]) >>2;
  2685.         index[7] = (int)(rindex1[7] + bindex1[7] + rindex2[7] + bindex2[7]) >>2;
  2686.     index += row_size;
  2687.     rindex1 += row_size;
  2688.     bindex1 += row_size;
  2689.     rindex2 += row_size;
  2690.     bindex2 += row_size;
  2691.       }
  2692.   }
  2693. }
  2694.  
  2695.  
  2696. /*
  2697.  *--------------------------------------------------------------
  2698.  *
  2699.  * ProcessSkippedPFrameMBlocks --
  2700.  *
  2701.  *    Processes skipped macroblocks in P frames.
  2702.  *
  2703.  * Results:
  2704.  *    Calculates pixel values for luminance, Cr, and Cb planes
  2705.  *      in current pict image for skipped macroblocks.
  2706.  *
  2707.  * Side effects:
  2708.  *    Pixel values in pict image changed.
  2709.  *
  2710.  *--------------------------------------------------------------
  2711.  */
  2712.  
  2713. static int
  2714. ProcessSkippedPFrameMBlocks(vid_stream)
  2715.      VidStream *vid_stream;
  2716. {
  2717.   int row_size, half_row, mb_row, mb_col, row, col, rr;
  2718.   int addr;
  2719.   unsigned char *dest, *src, *dest1, *src1;
  2720.  
  2721.   /* Calculate row sizes for luminance and Cr/Cb macroblock areas. */
  2722.  
  2723.   row_size = vid_stream->mb_width << 4;
  2724.   half_row = (row_size >> 1);
  2725.  
  2726.   /* For each skipped macroblock, do... */
  2727.  
  2728.   for(addr = vid_stream->mblock.past_mb_addr+1; 
  2729.       addr < vid_stream->mblock.mb_address; addr++) {
  2730.  
  2731.     /* Calculate macroblock row and col. */
  2732.  
  2733.     mb_row = addr / vid_stream->mb_width;
  2734.     mb_col = addr % vid_stream->mb_width;
  2735.  
  2736.     /* Calculate upper left pixel row,col for luminance plane. */
  2737.  
  2738.     row = mb_row << 4;
  2739.     col = mb_col << 4;
  2740.  
  2741.  
  2742.     /* For each row in macroblock luminance plane... */
  2743.  
  2744.     dest = vid_stream->current->luminance+(row*row_size)+col;
  2745.     src = vid_stream->future->luminance+(row*row_size)+col;
  2746.  
  2747.     for (rr = 0; rr < 16; rr++) {
  2748.  
  2749.       /* Copy pixel values from last I or P picture. */
  2750.  
  2751.       dest[0]  = src[0];
  2752.       dest[1]  = src[1];
  2753.       dest[2]  = src[2];
  2754.       dest[3]  = src[3];
  2755.       dest[4]  = src[4];
  2756.       dest[5]  = src[5];
  2757.       dest[6]  = src[6];
  2758.       dest[7]  = src[7];
  2759.       dest[8]  = src[8];
  2760.       dest[9]  = src[9];
  2761.       dest[10] = src[10];
  2762.       dest[11] = src[11];
  2763.       dest[12] = src[12];
  2764.       dest[13] = src[13];
  2765.       dest[14] = src[14];
  2766.       dest[15] = src[15];
  2767.       dest += row_size;
  2768.       src += row_size;
  2769.     }
  2770.     
  2771.     /* Divide row,col to get upper left pixel of macroblock in Cr
  2772.        and Cb planes.
  2773.        */
  2774.     
  2775.     row = row >> 1; col = col >> 1;
  2776.     
  2777.     /* For each row in Cr, and Cb planes... */
  2778.  
  2779.     dest = vid_stream->current->Cr+(row*half_row)+col;
  2780.     src = vid_stream->future->Cr+(row*half_row)+col;
  2781.     dest1 = vid_stream->current->Cb+(row*half_row)+col;
  2782.     src1 = vid_stream->future->Cb+(row*half_row)+col;
  2783.  
  2784.     for (rr = 0; rr < 8; rr++) {
  2785.       
  2786.       /* Copy pixel values from last I or P picture. */
  2787.       
  2788.       dest[0]  = src[0];
  2789.       dest[1]  = src[1];
  2790.       dest[2]  = src[2];
  2791.       dest[3]  = src[3];
  2792.       dest[4]  = src[4];
  2793.       dest[5]  = src[5];
  2794.       dest[6]  = src[6];
  2795.       dest[7]  = src[7];
  2796.  
  2797.       dest1[0] = src1[0];
  2798.       dest1[1] = src1[1];
  2799.       dest1[2] = src1[2];
  2800.       dest1[3] = src1[3];
  2801.       dest1[4] = src1[4];
  2802.       dest1[5] = src1[5];
  2803.       dest1[6] = src1[6];
  2804.       dest1[7] = src1[7];
  2805.  
  2806.       dest += half_row; src += half_row;
  2807.       dest1 += half_row; src1 += half_row;
  2808.     }
  2809.   }
  2810.   
  2811.   vid_stream->mblock.recon_right_for_prev = 0;
  2812.   vid_stream->mblock.recon_down_for_prev = 0;
  2813.  
  2814.   return PARSE_OK;
  2815. }
  2816.  
  2817.  
  2818.  
  2819. /*
  2820.  *--------------------------------------------------------------
  2821.  *
  2822.  * ProcessSkippedBFrameMBlocks --
  2823.  *
  2824.  *    Processes skipped macroblocks in B frames.
  2825.  *
  2826.  * Results:
  2827.  *    Calculates pixel values for luminance, Cr, and Cb planes
  2828.  *      in current pict image for skipped macroblocks.
  2829.  *
  2830.  * Side effects:
  2831.  *    Pixel values in pict image changed.
  2832.  *
  2833.  *--------------------------------------------------------------
  2834.  */
  2835.  
  2836. static int
  2837. ProcessSkippedBFrameMBlocks(vid_stream)
  2838.      VidStream *vid_stream;
  2839. {
  2840.   int row_size, half_row, mb_row, mb_col, row, col, rr, cc;
  2841.   int right_half_for, down_half_for, c_right_half_for, c_down_half_for;
  2842.   int right_half_back, down_half_back, c_right_half_back, c_down_half_back;
  2843.   int addr, right_for, down_for;
  2844.   int recon_right_for, recon_down_for;
  2845.   int recon_right_back, recon_down_back;
  2846.   int right_back, down_back;
  2847.   int c_right_for, c_down_for;
  2848.   int c_right_back, c_down_back;
  2849.   unsigned char forw_lum[256];
  2850.   unsigned char forw_cr[64], forw_cb[64];
  2851.   unsigned char back_lum[256], back_cr[64], back_cb[64];
  2852.   unsigned char *src, *src1, *src2, *src1a, *src2a;
  2853.   unsigned char *dest, *dest1;
  2854.  
  2855.   /* Calculate row sizes for luminance and Cr/Cb macroblock areas. */
  2856.  
  2857.   row_size = vid_stream->mb_width << 4;
  2858.   half_row = (row_size >> 1);
  2859.  
  2860.   /* Establish motion vector codes based on full pixel flag. */
  2861.  
  2862.   if (vid_stream->picture.full_pel_forw_vector) {
  2863.     recon_right_for = vid_stream->mblock.recon_right_for_prev << 1;
  2864.     recon_down_for = vid_stream->mblock.recon_down_for_prev << 1;
  2865.   }
  2866.   else {
  2867.     recon_right_for = vid_stream->mblock.recon_right_for_prev;
  2868.     recon_down_for = vid_stream->mblock.recon_down_for_prev;
  2869.   } 
  2870.  
  2871.   if (vid_stream->picture.full_pel_back_vector) {
  2872.     recon_right_back = vid_stream->mblock.recon_right_back_prev << 1;
  2873.     recon_down_back = vid_stream->mblock.recon_down_back_prev << 1;
  2874.   }
  2875.   else { 
  2876.     recon_right_back = vid_stream->mblock.recon_right_back_prev;
  2877.     recon_down_back = vid_stream->mblock.recon_down_back_prev;
  2878.   } 
  2879.  
  2880.  
  2881.   /* Calculate motion vectors. */
  2882.  
  2883.   if (vid_stream->mblock.bpict_past_forw) {
  2884.     right_for = recon_right_for >> 1;
  2885.     down_for = recon_down_for >> 1;
  2886.     right_half_for = recon_right_for & 0x1;
  2887.     down_half_for = recon_down_for & 0x1;
  2888.  
  2889.     c_right_for = recon_right_for >> 2;
  2890.     c_down_for = recon_down_for >> 2;
  2891.     c_right_half_for = recon_right_for & 0x2;
  2892.     c_down_half_for = recon_down_for & 0x2;
  2893.  
  2894.   }
  2895.   if (vid_stream->mblock.bpict_past_back) {
  2896.     right_back = recon_right_back >> 1;
  2897.     down_back = recon_down_back >> 1;
  2898.     right_half_back = recon_right_back & 0x1;
  2899.     down_half_back = recon_down_back & 0x1;
  2900.  
  2901.     c_right_back = recon_right_back >> 2;
  2902.     c_down_back = recon_down_back >> 2;
  2903.     c_right_half_back = recon_right_back & 0x2;
  2904.     c_down_half_back = recon_down_back & 0x2;
  2905.  
  2906.   }
  2907.  
  2908.  
  2909.   /* For each skipped macroblock, do... */
  2910.  
  2911.   for(addr = vid_stream->mblock.past_mb_addr+1; 
  2912.       addr < vid_stream->mblock.mb_address; addr++) {
  2913.  
  2914.     /* Calculate macroblock row and col. */
  2915.  
  2916.     mb_row = addr / vid_stream->mb_width;
  2917.     mb_col = addr % vid_stream->mb_width;
  2918.  
  2919.     /* Calculate upper left pixel row,col for luminance plane. */
  2920.  
  2921.     row = mb_row << 4;
  2922.     col = mb_col << 4;
  2923.  
  2924.     /* If forward predicted, calculate prediction values. */
  2925.  
  2926.     if (vid_stream->mblock.bpict_past_forw) {
  2927.       ReconSkippedBlock(vid_stream->past->luminance, forw_lum, 
  2928.             row, col, row_size, right_for, down_for,
  2929.             right_half_for, down_half_for, 16);
  2930.       ReconSkippedBlock(vid_stream->past->Cr, forw_cr, (row>>1),
  2931.             (col>>1), (row_size>>1),
  2932.             c_right_for, c_down_for, c_right_half_for, c_down_half_for, 8);
  2933.       ReconSkippedBlock(vid_stream->past->Cb, forw_cb, (row>>1),
  2934.             (col>>1), (row_size>>1),
  2935.             c_right_for, c_down_for, c_right_half_for, c_down_half_for, 8);
  2936.     }
  2937.  
  2938.     /* If back predicted, calculate prediction values. */
  2939.  
  2940.     if (vid_stream->mblock.bpict_past_back) {
  2941.       ReconSkippedBlock(vid_stream->future->luminance, back_lum, 
  2942.             row, col, row_size, right_back, down_back,
  2943.             right_half_back, down_half_back, 16);
  2944.       ReconSkippedBlock(vid_stream->future->Cr, back_cr, (row>>1),
  2945.             (col>>1), (row_size>>1),
  2946.             c_right_back, c_down_back, 
  2947.             c_right_half_back, c_down_half_back, 8);
  2948.       ReconSkippedBlock(vid_stream->future->Cb, back_cb, (row>>1),
  2949.             (col>>1), (row_size>>1),
  2950.             c_right_back, c_down_back, 
  2951.             c_right_half_back, c_down_half_back, 8);
  2952.     }
  2953.  
  2954.     if (vid_stream->mblock.bpict_past_forw && 
  2955.     (!vid_stream->mblock.bpict_past_back)) {
  2956.  
  2957.       dest = vid_stream->current->luminance+(row*row_size)+col;
  2958.       src = forw_lum;
  2959.  
  2960.       for (rr = 0; rr < 16; rr++) {
  2961.  
  2962.     /* memcpy(dest, forw_lum+(rr<<4), 16);  */
  2963.         dest[0]  = src[0];
  2964.     dest[1]  = src[1];
  2965.     dest[2]  = src[2];
  2966.     dest[3]  = src[3];
  2967.         dest[4]  = src[4];
  2968.     dest[5]  = src[5];
  2969.     dest[6]  = src[6];
  2970.     dest[7]  = src[7];
  2971.         dest[8]  = src[8];
  2972.     dest[9]  = src[9];
  2973.     dest[10] = src[10];
  2974.     dest[11] = src[11];
  2975.         dest[12] = src[12];
  2976.     dest[13] = src[13];
  2977.     dest[14] = src[14];
  2978.     dest[15] = src[15];
  2979.     dest += row_size;
  2980.     src += 16;
  2981.       }
  2982.  
  2983.       row /= 2; col /= 2;
  2984.       dest = vid_stream->current->Cr+(row*half_row)+col;
  2985.       dest1 = vid_stream->current->Cb+(row*half_row)+col;
  2986.       src = forw_cr;
  2987.       src1 = forw_cb;
  2988.  
  2989.       for (rr = 0; rr < 8; rr++) {
  2990.     /* 
  2991.      * memcpy(dest, forw_cr+(rr<<3), 8);
  2992.      * memcpy(dest1, forw_cb+(rr<<3), 8);
  2993.      */
  2994.  
  2995.         dest[0]  = src[0];
  2996.     dest[1]  = src[1];
  2997.     dest[2]  = src[2];
  2998.     dest[3]  = src[3];
  2999.         dest[4]  = src[4];
  3000.     dest[5]  = src[5];
  3001.     dest[6]  = src[6];
  3002.     dest[7]  = src[7];
  3003.  
  3004.         dest1[0] = src1[0];
  3005.     dest1[1] = src1[1];
  3006.     dest1[2] = src1[2];
  3007.     dest1[3] = src1[3];
  3008.         dest1[4] = src1[4];
  3009.     dest1[5] = src1[5];
  3010.     dest1[6] = src1[6];
  3011.     dest1[7] = src1[7];
  3012.  
  3013.     dest += half_row;
  3014.     dest1 += half_row;
  3015.     src += 8;
  3016.     src1 += 8;
  3017.       }
  3018.     }
  3019.  
  3020.     else if  (vid_stream->mblock.bpict_past_back && 
  3021.           (!vid_stream->mblock.bpict_past_forw)) {
  3022.       
  3023.       dest = vid_stream->current->luminance+(row*row_size)+col;
  3024.  
  3025.       for (rr = 0; rr < 16; rr++) {
  3026.     memcpy(dest, back_lum+(rr<<4), 16);
  3027.     dest += row_size;
  3028.       }
  3029.  
  3030.       row /= 2; col /= 2;
  3031.  
  3032.       dest = vid_stream->current->Cr+(row*half_row)+col;
  3033.       dest1 = vid_stream->current->Cb+(row*half_row)+col;
  3034.       src = back_cr;
  3035.       src1 = back_cb;
  3036.  
  3037.       for (rr = 0; rr < 8; rr++) {
  3038.     /*
  3039.      * memcpy(dest, back_cr+(rr<<3), 8);
  3040.      * memcpy(dest1, back_cb+(rr<<3), 8);
  3041.      */
  3042.  
  3043.         dest[0]  = src[0];
  3044.     dest[1]  = src[1];
  3045.     dest[2]  = src[2];
  3046.     dest[3]  = src[3];
  3047.         dest[4]  = src[4];
  3048.     dest[5]  = src[5];
  3049.     dest[6]  = src[6];
  3050.     dest[7]  = src[7];
  3051.  
  3052.         dest1[0] = src1[0];
  3053.     dest1[1] = src1[1];
  3054.     dest1[2] = src1[2];
  3055.     dest1[3] = src1[3];
  3056.         dest1[4] = src1[4];
  3057.     dest1[5] = src1[5];
  3058.     dest1[6] = src1[6];
  3059.     dest1[7] = src1[7];
  3060.  
  3061.     dest += half_row;
  3062.     dest1 += half_row;
  3063.     src += 8;
  3064.     src1 += 8;
  3065.       }
  3066.     }
  3067.     else {
  3068.  
  3069.       dest = vid_stream->current->luminance+(row*row_size)+col;
  3070.       src1 = forw_lum; src2 = back_lum;
  3071.  
  3072.       for (rr = 0; rr < 16; rr++) {
  3073.           dest[0] = (int)(src1[0] + src2[0]) >> 1;
  3074.           dest[1] = (int)(src1[1] + src2[1]) >> 1;
  3075.           dest[2] = (int)(src1[2] + src2[2]) >> 1;
  3076.           dest[3] = (int)(src1[3] + src2[3]) >> 1;
  3077.           dest[4] = (int)(src1[4] + src2[4]) >> 1;
  3078.           dest[5] = (int)(src1[5] + src2[5]) >> 1;
  3079.           dest[6] = (int)(src1[6] + src2[6]) >> 1;
  3080.           dest[7] = (int)(src1[7] + src2[7]) >> 1;
  3081.           dest[8] = (int)(src1[8] + src2[8]) >> 1;
  3082.           dest[9] = (int)(src1[9] + src2[9]) >> 1;
  3083.           dest[10] = (int)(src1[10] + src2[10]) >> 1;
  3084.           dest[11] = (int)(src1[11] + src2[11]) >> 1;
  3085.           dest[12] = (int)(src1[12] + src2[12]) >> 1;
  3086.           dest[13] = (int)(src1[13] + src2[13]) >> 1;
  3087.           dest[14] = (int)(src1[14] + src2[14]) >> 1;
  3088.           dest[15] = (int)(src1[15] + src2[15]) >> 1;
  3089.       dest += row_size;
  3090.       src1 += 16;
  3091.       src2 += 16;
  3092.       }
  3093.  
  3094.       row /= 2; col /= 2;
  3095.  
  3096.       dest = vid_stream->current->Cr+(row*half_row)+col;
  3097.       dest1 = vid_stream->current->Cb+(row*half_row)+col;
  3098.       src1 = forw_cr; src2 = back_cr;
  3099.       src1a = forw_cb; src2a = back_cb;
  3100.  
  3101.       for (rr = 0; rr < 8; rr++) {
  3102.         dest[0] = (int)(src1[0] + src2[0]) >> 1;
  3103.         dest[1] = (int)(src1[1] + src2[1]) >> 1;
  3104.         dest[2] = (int)(src1[2] + src2[2]) >> 1;
  3105.         dest[3] = (int)(src1[3] + src2[3]) >> 1;
  3106.         dest[4] = (int)(src1[4] + src2[4]) >> 1;
  3107.         dest[5] = (int)(src1[5] + src2[5]) >> 1;
  3108.         dest[6] = (int)(src1[6] + src2[6]) >> 1;
  3109.         dest[7] = (int)(src1[7] + src2[7]) >> 1;
  3110.     dest += half_row;
  3111.         src1 += 8;
  3112.         src2 += 8;
  3113.  
  3114.         dest1[0] = (int)(src1a[0] + src2a[0]) >> 1;
  3115.         dest1[1] = (int)(src1a[1] + src2a[1]) >> 1;
  3116.         dest1[2] = (int)(src1a[2] + src2a[2]) >> 1;
  3117.         dest1[3] = (int)(src1a[3] + src2a[3]) >> 1;
  3118.         dest1[4] = (int)(src1a[4] + src2a[4]) >> 1;
  3119.         dest1[5] = (int)(src1a[5] + src2a[5]) >> 1;
  3120.         dest1[6] = (int)(src1a[6] + src2a[6]) >> 1;
  3121.         dest1[7] = (int)(src1a[7] + src2a[7]) >> 1;
  3122.     dest1 += half_row;
  3123.         src1a += 8;
  3124.         src2a += 8;
  3125.       }
  3126.     }
  3127.   }
  3128.  
  3129.   return PARSE_OK;
  3130. }
  3131.  
  3132.  
  3133.  
  3134. /*
  3135.  *--------------------------------------------------------------
  3136.  *
  3137.  * ReconSkippedBlock --
  3138.  *
  3139.  *    Reconstructs predictive block for skipped macroblocks
  3140.  *      in B Frames.
  3141.  *
  3142.  * Results:
  3143.  *    No return values.
  3144.  *
  3145.  * Side effects:
  3146.  *    None.
  3147.  *
  3148.  *--------------------------------------------------------------
  3149.  */
  3150.  
  3151. static void 
  3152. ReconSkippedBlock(source, dest,  row, col, row_size, 
  3153.           right, down, right_half, down_half, width)
  3154.      unsigned char *source;
  3155.      unsigned char *dest;
  3156.      int row, col, row_size, right, down, right_half, down_half, width;
  3157. {
  3158.   int rr, cc;
  3159.   unsigned char *source2;
  3160.  
  3161.   source += ((row+down)*row_size)+col+right;
  3162.  
  3163.   if (width == 16) {
  3164.       if ((!right_half) && (!down_half)) {
  3165.     for (rr =0 ; rr < width; rr++) {
  3166.           dest[0]  = source[0];
  3167.       dest[1]  = source[1];
  3168.       dest[2]  = source[2];
  3169.       dest[3]  = source[3];
  3170.           dest[4]  = source[4];
  3171.       dest[5]  = source[5];
  3172.       dest[6]  = source[6];
  3173.       dest[7]  = source[7];
  3174.           dest[8]  = source[8];
  3175.       dest[9]  = source[9];
  3176.       dest[10] = source[10];
  3177.       dest[11] = source[11];
  3178.           dest[12] = source[12];
  3179.       dest[13] = source[13];
  3180.       dest[14] = source[14];
  3181.       dest[15] = source[15];
  3182.       dest += width;
  3183.       source += row_size;
  3184.     }
  3185.       }
  3186.       else {
  3187.     source2 = source + right_half + (row_size * down_half);
  3188.     for (rr =0 ; rr < width; rr++) {
  3189.           dest[0] = (int)(source[0] + source2[0]) >> 1;
  3190.           dest[1] = (int)(source[1] + source2[1]) >> 1;
  3191.           dest[2] = (int)(source[2] + source2[2]) >> 1;
  3192.           dest[3] = (int)(source[3] + source2[3]) >> 1;
  3193.           dest[4] = (int)(source[4] + source2[4]) >> 1;
  3194.           dest[5] = (int)(source[5] + source2[5]) >> 1;
  3195.           dest[6] = (int)(source[6] + source2[6]) >> 1;
  3196.           dest[7] = (int)(source[7] + source2[7]) >> 1;
  3197.           dest[8] = (int)(source[8] + source2[8]) >> 1;
  3198.           dest[9] = (int)(source[9] + source2[9]) >> 1;
  3199.           dest[10] = (int)(source[10] + source2[10]) >> 1;
  3200.           dest[11] = (int)(source[11] + source2[11]) >> 1;
  3201.           dest[12] = (int)(source[12] + source2[12]) >> 1;
  3202.           dest[13] = (int)(source[13] + source2[13]) >> 1;
  3203.           dest[14] = (int)(source[14] + source2[14]) >> 1;
  3204.           dest[15] = (int)(source[15] + source2[15]) >> 1;
  3205.       dest += width;
  3206.       source += row_size;
  3207.       source2 += row_size;
  3208.     }
  3209.       }
  3210.   } else /* (width == 8) */ {
  3211.       assert (width == 8);
  3212.       if ((!right_half) && (!down_half)) {
  3213.     for (rr =0 ; rr < width; rr++) {
  3214.           dest[0]  = source[0];
  3215.       dest[1]  = source[1];
  3216.       dest[2]  = source[2];
  3217.       dest[3]  = source[3];
  3218.           dest[4]  = source[4];
  3219.       dest[5]  = source[5];
  3220.       dest[6]  = source[6];
  3221.       dest[7]  = source[7];
  3222.       dest += width;
  3223.       source += row_size;
  3224.     }
  3225.       }
  3226.       else {
  3227.     source2 = source + right_half + (row_size * down_half);
  3228.     for (rr =0 ; rr < width; rr++) {
  3229.           dest[0] = (int)(source[0] + source2[0]) >> 1;
  3230.           dest[1] = (int)(source[1] + source2[1]) >> 1;
  3231.           dest[2] = (int)(source[2] + source2[2]) >> 1;
  3232.           dest[3] = (int)(source[3] + source2[3]) >> 1;
  3233.           dest[4] = (int)(source[4] + source2[4]) >> 1;
  3234.           dest[5] = (int)(source[5] + source2[5]) >> 1;
  3235.           dest[6] = (int)(source[6] + source2[6]) >> 1;
  3236.           dest[7] = (int)(source[7] + source2[7]) >> 1;
  3237.       dest += width;
  3238.       source += row_size;
  3239.       source2 += row_size;
  3240.     }
  3241.       }
  3242.   }
  3243. }
  3244.  
  3245.  
  3246. /*
  3247.  *--------------------------------------------------------------
  3248.  *
  3249.  * DoPictureDisplay --
  3250.  *
  3251.  *    Converts image from Lum, Cr, Cb to colormap space. Puts
  3252.  *      image in lum plane. Updates past and future frame
  3253.  *      pointers. Dithers image. Sends to display mechanism.
  3254.  *
  3255.  * Results:
  3256.  *    Pict image structure locked if displaying or if frame
  3257.  *      is needed as past or future reference.
  3258.  *
  3259.  * Side effects:
  3260.  *    Lum plane pummelled.
  3261.  *
  3262.  *--------------------------------------------------------------
  3263.  */
  3264.   
  3265. static void 
  3266. DoPictureDisplay(vid_stream)
  3267. VidStream *vid_stream;
  3268. {
  3269.  
  3270.   /* Convert to colormap space and dither. */
  3271.  
  3272.   DoDitherImage(vid_stream->current->luminance, vid_stream->current->Cr,
  3273.           vid_stream->current->Cb, vid_stream->current->display,
  3274.           vid_stream->mb_height*16, vid_stream->mb_width*16);
  3275.  
  3276.   /* Update past and future references if needed. */
  3277.  
  3278.   if ((vid_stream->picture.code_type == I_TYPE) || (vid_stream->picture.code_type == P_TYPE)) {
  3279.     if (vid_stream->future == NULL) {
  3280.       vid_stream->future = vid_stream->current;
  3281.       vid_stream->future->locked |= FUTURE_LOCK;
  3282.     } else {
  3283.       if (vid_stream->past != NULL) {
  3284.     vid_stream->past->locked &= ~PAST_LOCK;
  3285.       }
  3286.       vid_stream->past = vid_stream->future;
  3287.       vid_stream->past->locked &= ~FUTURE_LOCK;
  3288.       vid_stream->past->locked |= PAST_LOCK;
  3289.       vid_stream->future = vid_stream->current;
  3290.       vid_stream->future->locked |= FUTURE_LOCK;
  3291.       vid_stream->current = vid_stream->past;
  3292.       ExecuteDisplay(vid_stream);
  3293.     }
  3294.   }
  3295.   else ExecuteDisplay(vid_stream);
  3296.  
  3297. }
  3298.  
  3299.  
  3300. /*
  3301.  *--------------------------------------------------------------
  3302.  *
  3303.  * ToggleBFlag --
  3304.  *
  3305.  *    Called to set no b frame processing flag.
  3306.  *
  3307.  * Results:
  3308.  *      No_B_Flag flag is toggled from present value to opposite value.
  3309.  *
  3310.  * Side effects:
  3311.  *      None.
  3312.  *
  3313.  *--------------------------------------------------------------
  3314.  */
  3315.  
  3316. void
  3317. ToggleBFlag()
  3318. {
  3319.   if (No_B_Flag) {
  3320.     No_B_Flag = 0;
  3321.   } else No_B_Flag = 1;
  3322. }
  3323.  
  3324.  
  3325.  
  3326. /*
  3327.  *--------------------------------------------------------------
  3328.  *
  3329.  * TogglePFlag --
  3330.  *
  3331.  *    Called to set no p frame processing flag.
  3332.  *
  3333.  * Results:
  3334.  *      No_P_Flag flag is toggled from present value to opposite value.
  3335.  *
  3336.  * Side effects:
  3337.  *      None.
  3338.  *
  3339.  *--------------------------------------------------------------
  3340.  */
  3341.  
  3342. void
  3343. TogglePFlag()
  3344. {
  3345.   if (No_P_Flag) {
  3346.     No_P_Flag = 0;
  3347.   } else No_P_Flag = 1;
  3348. }
  3349.  
  3350.